Expanded type coverage to benchmarks, samples and tests. (#566)
* Renamed json samples to fix duplicate module name. Signed-off-by: dblock <[email protected]> * Enabled mypy on all source files. Signed-off-by: dblock <[email protected]> * Added missing types. Signed-off-by: dblock <[email protected]> * Added CHANGELOG. Signed-off-by: dblock <[email protected]> * Move type: ignore to fix untyped decorator makes function untyped. Signed-off-by: dblock <[email protected]> * Fix nox -rs lint-3.7. Signed-off-by: dblock <[email protected]> * Fixed incorrect import. Signed-off-by: dblock <[email protected]> * Fix broken test. Signed-off-by: dblock <[email protected]> * Fixed TestBulk::test_bulk_works_with_bytestring_body. Signed-off-by: dblock <[email protected]> --------- Signed-off-by: dblock <[email protected]>
This commit is contained in:
@@ -24,6 +24,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
|||||||
- Generate `cat` client from API specs ([#529](https://github.com/opensearch-project/opensearch-py/pull/529))
|
- Generate `cat` client from API specs ([#529](https://github.com/opensearch-project/opensearch-py/pull/529))
|
||||||
- Use API generator for all APIs ([#551](https://github.com/opensearch-project/opensearch-py/pull/551))
|
- Use API generator for all APIs ([#551](https://github.com/opensearch-project/opensearch-py/pull/551))
|
||||||
- Merge `.pyi` type stubs inline ([#563](https://github.com/opensearch-project/opensearch-py/pull/563))
|
- Merge `.pyi` type stubs inline ([#563](https://github.com/opensearch-project/opensearch-py/pull/563))
|
||||||
|
- Expanded type coverage to benchmarks, samples and tests ([#566](https://github.com/opensearch-project/opensearch-py/pull/566))
|
||||||
### Deprecated
|
### Deprecated
|
||||||
- Deprecated point-in-time APIs (list_all_point_in_time, create_point_in_time, delete_point_in_time) and Security Client APIs (health_check and update_audit_config) ([#502](https://github.com/opensearch-project/opensearch-py/pull/502))
|
- Deprecated point-in-time APIs (list_all_point_in_time, create_point_in_time, delete_point_in_time) and Security Client APIs (health_check and update_audit_config) ([#502](https://github.com/opensearch-project/opensearch-py/pull/502))
|
||||||
### Removed
|
### Removed
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import uuid
|
import uuid
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from opensearchpy import AsyncHttpConnection, AsyncOpenSearch
|
from opensearchpy import AsyncHttpConnection, AsyncOpenSearch
|
||||||
|
|
||||||
@@ -22,7 +23,7 @@ index_name = "test-index-async"
|
|||||||
item_count = 100
|
item_count = 100
|
||||||
|
|
||||||
|
|
||||||
async def index_records(client, item_count) -> None:
|
async def index_records(client: Any, item_count: int) -> None:
|
||||||
await asyncio.gather(
|
await asyncio.gather(
|
||||||
*[
|
*[
|
||||||
client.index(
|
client.index(
|
||||||
@@ -39,7 +40,7 @@ async def index_records(client, item_count) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def test_async(client_count=1, item_count=1):
|
async def test_async(client_count: int = 1, item_count: int = 1) -> None:
|
||||||
clients = []
|
clients = []
|
||||||
for i in range(client_count):
|
for i in range(client_count):
|
||||||
clients.append(
|
clients.append(
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
import logging
|
import logging
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from thread_with_return_value import ThreadWithReturnValue
|
from thread_with_return_value import ThreadWithReturnValue
|
||||||
|
|
||||||
@@ -36,8 +37,8 @@ handler.setFormatter(formatter)
|
|||||||
root.addHandler(handler)
|
root.addHandler(handler)
|
||||||
|
|
||||||
|
|
||||||
def get_info(client, request_count):
|
def get_info(client: Any, request_count: int) -> float:
|
||||||
tt = 0
|
tt: float = 0
|
||||||
for n in range(request_count):
|
for n in range(request_count):
|
||||||
start = time.time() * 1000
|
start = time.time() * 1000
|
||||||
client.info()
|
client.info()
|
||||||
@@ -46,7 +47,7 @@ def get_info(client, request_count):
|
|||||||
return tt
|
return tt
|
||||||
|
|
||||||
|
|
||||||
def test(thread_count=1, request_count=1, client_count=1):
|
def test(thread_count: int = 1, request_count: int = 1, client_count: int = 1) -> None:
|
||||||
clients = []
|
clients = []
|
||||||
for i in range(client_count):
|
for i in range(client_count):
|
||||||
clients.append(
|
clients.append(
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import logging
|
|||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import uuid
|
import uuid
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from thread_with_return_value import ThreadWithReturnValue
|
from thread_with_return_value import ThreadWithReturnValue
|
||||||
|
|
||||||
@@ -37,10 +38,10 @@ handler.setFormatter(formatter)
|
|||||||
root.addHandler(handler)
|
root.addHandler(handler)
|
||||||
|
|
||||||
|
|
||||||
def index_records(client, item_count):
|
def index_records(client: Any, item_count: int) -> Any:
|
||||||
tt = 0
|
tt = 0
|
||||||
for n in range(10):
|
for n in range(10):
|
||||||
data = []
|
data: Any = []
|
||||||
for i in range(item_count):
|
for i in range(item_count):
|
||||||
data.append(
|
data.append(
|
||||||
json.dumps({"index": {"_index": index_name, "_id": str(uuid.uuid4())}})
|
json.dumps({"index": {"_index": index_name, "_id": str(uuid.uuid4())}})
|
||||||
@@ -63,7 +64,7 @@ def index_records(client, item_count):
|
|||||||
return tt
|
return tt
|
||||||
|
|
||||||
|
|
||||||
def test(thread_count=1, item_count=1, client_count=1):
|
def test(thread_count: int = 1, item_count: int = 1, client_count: int = 1) -> None:
|
||||||
clients = []
|
clients = []
|
||||||
for i in range(client_count):
|
for i in range(client_count):
|
||||||
clients.append(
|
clients.append(
|
||||||
|
|||||||
@@ -10,19 +10,30 @@
|
|||||||
|
|
||||||
|
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
|
from typing import Any, Optional
|
||||||
|
|
||||||
|
|
||||||
class ThreadWithReturnValue(Thread):
|
class ThreadWithReturnValue(Thread):
|
||||||
|
_target: Any
|
||||||
|
_args: Any
|
||||||
|
_kwargs: Any
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self, group=None, target=None, name=None, args=(), kwargs={}, Verbose=None
|
self,
|
||||||
):
|
group: Any = None,
|
||||||
|
target: Any = None,
|
||||||
|
name: Optional[str] = None,
|
||||||
|
args: Any = (),
|
||||||
|
kwargs: Any = {},
|
||||||
|
Verbose: Optional[bool] = None,
|
||||||
|
) -> None:
|
||||||
Thread.__init__(self, group, target, name, args, kwargs)
|
Thread.__init__(self, group, target, name, args, kwargs)
|
||||||
self._return = None
|
self._return = None
|
||||||
|
|
||||||
def run(self):
|
def run(self) -> None:
|
||||||
if self._target is not None:
|
if self._target is not None:
|
||||||
self._return = self._target(*self._args, **self._kwargs)
|
self._return = self._target(*self._args, **self._kwargs)
|
||||||
|
|
||||||
def join(self, *args):
|
def join(self, *args: Any) -> Any:
|
||||||
Thread.join(self, *args)
|
Thread.join(self, *args)
|
||||||
return self._return
|
return self._return
|
||||||
|
|||||||
+18
-16
@@ -26,9 +26,11 @@
|
|||||||
|
|
||||||
# -- Project information -----------------------------------------------------
|
# -- Project information -----------------------------------------------------
|
||||||
|
|
||||||
project = "OpenSearch Python Client"
|
from typing import Any
|
||||||
copyright = "OpenSearch Project Contributors"
|
|
||||||
author = "OpenSearch Project Contributors"
|
project: str = "OpenSearch Python Client"
|
||||||
|
copyright: str = "OpenSearch Project Contributors"
|
||||||
|
author: str = "OpenSearch Project Contributors"
|
||||||
|
|
||||||
|
|
||||||
# -- General configuration ---------------------------------------------------
|
# -- General configuration ---------------------------------------------------
|
||||||
@@ -36,7 +38,7 @@ author = "OpenSearch Project Contributors"
|
|||||||
# Add any Sphinx extension module names here, as strings. They can be
|
# Add any Sphinx extension module names here, as strings. They can be
|
||||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||||
# ones.
|
# ones.
|
||||||
extensions = [
|
extensions: Any = [
|
||||||
"sphinx.ext.autodoc",
|
"sphinx.ext.autodoc",
|
||||||
"sphinx_rtd_theme",
|
"sphinx_rtd_theme",
|
||||||
"sphinx.ext.viewcode",
|
"sphinx.ext.viewcode",
|
||||||
@@ -47,12 +49,12 @@ extensions = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
# Add any paths that contain templates here, relative to this directory.
|
# Add any paths that contain templates here, relative to this directory.
|
||||||
templates_path = ["_templates"]
|
templates_path: Any = ["_templates"]
|
||||||
|
|
||||||
# List of patterns, relative to source directory, that match files and
|
# List of patterns, relative to source directory, that match files and
|
||||||
# directories to ignore when looking for source files.
|
# directories to ignore when looking for source files.
|
||||||
# This pattern also affects html_static_path and html_extra_path.
|
# This pattern also affects html_static_path and html_extra_path.
|
||||||
exclude_patterns = []
|
exclude_patterns: Any = []
|
||||||
|
|
||||||
|
|
||||||
# -- Options for HTML output -------------------------------------------------
|
# -- Options for HTML output -------------------------------------------------
|
||||||
@@ -60,31 +62,31 @@ exclude_patterns = []
|
|||||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||||
# a list of builtin themes.
|
# a list of builtin themes.
|
||||||
#
|
#
|
||||||
html_theme = "sphinx_rtd_theme"
|
html_theme: str = "sphinx_rtd_theme"
|
||||||
|
|
||||||
# Add any paths that contain custom static files (such as style sheets) here,
|
# Add any paths that contain custom static files (such as style sheets) here,
|
||||||
# relative to this directory. They are copied after the builtin static files,
|
# relative to this directory. They are copied after the builtin static files,
|
||||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||||
html_static_path = ["_static"]
|
html_static_path: Any = ["_static"]
|
||||||
|
|
||||||
# -- additional settings -------------------------------------------------
|
# -- additional settings -------------------------------------------------
|
||||||
intersphinx_mapping = {
|
intersphinx_mapping: Any = {
|
||||||
"python": ("https://docs.python.org/3", None),
|
"python": ("https://docs.python.org/3", None),
|
||||||
}
|
}
|
||||||
|
|
||||||
html_logo = "imgs/OpenSearch.svg"
|
html_logo: str = "imgs/OpenSearch.svg"
|
||||||
|
|
||||||
# These paths are either relative to html_static_path
|
# These paths are either relative to html_static_path
|
||||||
# or fully qualified paths (eg. https://...)
|
# or fully qualified paths (eg. https://...)
|
||||||
html_css_files = [
|
html_css_files: Any = [
|
||||||
"css/custom.css",
|
"css/custom.css",
|
||||||
]
|
]
|
||||||
|
|
||||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||||
html_show_sphinx = False
|
html_show_sphinx: bool = False
|
||||||
|
|
||||||
# add github link
|
# add github link
|
||||||
html_context = {
|
html_context: Any = {
|
||||||
"display_github": True,
|
"display_github": True,
|
||||||
"github_user": "opensearch-project",
|
"github_user": "opensearch-project",
|
||||||
"github_repo": "opensearch-py",
|
"github_repo": "opensearch-py",
|
||||||
@@ -94,18 +96,18 @@ html_context = {
|
|||||||
# -- autodoc config -------------------------------------------------
|
# -- autodoc config -------------------------------------------------
|
||||||
# This value controls how to represent typehints.
|
# This value controls how to represent typehints.
|
||||||
# https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#confval-autodoc_typehints
|
# https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#confval-autodoc_typehints
|
||||||
autodoc_typehints = "description"
|
autodoc_typehints: str = "description"
|
||||||
|
|
||||||
# This value selects what content will be inserted into the main body of an autoclass directive.
|
# This value selects what content will be inserted into the main body of an autoclass directive.
|
||||||
# https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#confval-autoclass_content
|
# https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#confval-autoclass_content
|
||||||
autoclass_content = "both"
|
autoclass_content: str = "both"
|
||||||
|
|
||||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-add_module_names
|
# https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-add_module_names
|
||||||
# add_module_names = False
|
# add_module_names = False
|
||||||
|
|
||||||
# The default options for autodoc directives.
|
# The default options for autodoc directives.
|
||||||
# https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#confval-autodoc_default_options
|
# https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#confval-autodoc_default_options
|
||||||
autodoc_default_options = {
|
autodoc_default_options: Any = {
|
||||||
# If set, autodoc will generate document for the members of the target module, class or exception. # noqa: E501
|
# If set, autodoc will generate document for the members of the target module, class or exception. # noqa: E501
|
||||||
# https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#directive-option-automodule-members
|
# https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#directive-option-automodule-members
|
||||||
"members": True,
|
"members": True,
|
||||||
|
|||||||
+16
-11
@@ -26,6 +26,8 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import nox
|
import nox
|
||||||
|
|
||||||
SOURCE_FILES = (
|
SOURCE_FILES = (
|
||||||
@@ -40,16 +42,16 @@ SOURCE_FILES = (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@nox.session(python=["3.6", "3.7", "3.8", "3.9", "3.10", "3.11"])
|
@nox.session(python=["3.6", "3.7", "3.8", "3.9", "3.10", "3.11"]) # type: ignore
|
||||||
def test(session) -> None:
|
def test(session: Any) -> None:
|
||||||
session.install(".")
|
session.install(".")
|
||||||
session.install("-r", "dev-requirements.txt")
|
session.install("-r", "dev-requirements.txt")
|
||||||
|
|
||||||
session.run("python", "setup.py", "test")
|
session.run("python", "setup.py", "test")
|
||||||
|
|
||||||
|
|
||||||
@nox.session()
|
@nox.session() # type: ignore
|
||||||
def format(session) -> None:
|
def format(session: Any) -> None:
|
||||||
session.install("black", "isort")
|
session.install("black", "isort")
|
||||||
|
|
||||||
session.run("isort", "--profile=black", *SOURCE_FILES)
|
session.run("isort", "--profile=black", *SOURCE_FILES)
|
||||||
@@ -59,8 +61,8 @@ def format(session) -> None:
|
|||||||
lint(session)
|
lint(session)
|
||||||
|
|
||||||
|
|
||||||
@nox.session(python=["3.7"])
|
@nox.session(python=["3.7"]) # type: ignore
|
||||||
def lint(session) -> None:
|
def lint(session: Any) -> None:
|
||||||
session.install(
|
session.install(
|
||||||
"flake8",
|
"flake8",
|
||||||
"black",
|
"black",
|
||||||
@@ -70,6 +72,9 @@ def lint(session) -> None:
|
|||||||
"types-six",
|
"types-six",
|
||||||
"types-simplejson",
|
"types-simplejson",
|
||||||
"types-python-dateutil",
|
"types-python-dateutil",
|
||||||
|
"types-PyYAML",
|
||||||
|
"types-mock",
|
||||||
|
"types-pytz",
|
||||||
)
|
)
|
||||||
|
|
||||||
session.run("isort", "--check", "--profile=black", *SOURCE_FILES)
|
session.run("isort", "--check", "--profile=black", *SOURCE_FILES)
|
||||||
@@ -82,7 +87,7 @@ def lint(session) -> None:
|
|||||||
|
|
||||||
# Run mypy on the package and then the type examples separately for
|
# Run mypy on the package and then the type examples separately for
|
||||||
# the two different mypy use-cases, ourselves and our users.
|
# the two different mypy use-cases, ourselves and our users.
|
||||||
session.run("mypy", "--strict", "opensearchpy/")
|
session.run("mypy", "--strict", *SOURCE_FILES)
|
||||||
session.run("mypy", "--strict", "test_opensearchpy/test_types/sync_types.py")
|
session.run("mypy", "--strict", "test_opensearchpy/test_types/sync_types.py")
|
||||||
session.run("mypy", "--strict", "test_opensearchpy/test_types/async_types.py")
|
session.run("mypy", "--strict", "test_opensearchpy/test_types/async_types.py")
|
||||||
|
|
||||||
@@ -93,8 +98,8 @@ def lint(session) -> None:
|
|||||||
session.run("mypy", "--strict", "test_opensearchpy/test_types/sync_types.py")
|
session.run("mypy", "--strict", "test_opensearchpy/test_types/sync_types.py")
|
||||||
|
|
||||||
|
|
||||||
@nox.session()
|
@nox.session() # type: ignore
|
||||||
def docs(session) -> None:
|
def docs(session: Any) -> None:
|
||||||
session.install(".")
|
session.install(".")
|
||||||
session.install(
|
session.install(
|
||||||
"-rdev-requirements.txt", "sphinx-rtd-theme", "sphinx-autodoc-typehints"
|
"-rdev-requirements.txt", "sphinx-rtd-theme", "sphinx-autodoc-typehints"
|
||||||
@@ -102,8 +107,8 @@ def docs(session) -> None:
|
|||||||
session.run("python", "-m", "pip", "install", "sphinx-autodoc-typehints")
|
session.run("python", "-m", "pip", "install", "sphinx-autodoc-typehints")
|
||||||
|
|
||||||
|
|
||||||
@nox.session()
|
@nox.session() # type: ignore
|
||||||
def generate(session) -> None:
|
def generate(session: Any) -> None:
|
||||||
session.install("-rdev-requirements.txt")
|
session.install("-rdev-requirements.txt")
|
||||||
session.run("python", "utils/generate-api.py")
|
session.run("python", "utils/generate-api.py")
|
||||||
format(session)
|
format(session)
|
||||||
|
|||||||
@@ -256,4 +256,5 @@ __all__ = [
|
|||||||
"AsyncTransport",
|
"AsyncTransport",
|
||||||
"AsyncOpenSearch",
|
"AsyncOpenSearch",
|
||||||
"AsyncHttpConnection",
|
"AsyncHttpConnection",
|
||||||
|
"__versionstr__",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
import collections.abc as collections_abc
|
import collections.abc as collections_abc
|
||||||
from fnmatch import fnmatch
|
from fnmatch import fnmatch
|
||||||
from typing import Any, Optional, Sequence, Tuple, Type
|
from typing import Any, Optional, Tuple, Type
|
||||||
|
|
||||||
from six import add_metaclass
|
from six import add_metaclass
|
||||||
|
|
||||||
@@ -128,9 +128,7 @@ class AsyncDocument(ObjectBase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def search(
|
def search(cls, using: Any = None, index: Any = None) -> AsyncSearch:
|
||||||
cls, using: Optional[AsyncOpenSearch] = None, index: Optional[str] = None
|
|
||||||
) -> AsyncSearch:
|
|
||||||
"""
|
"""
|
||||||
Create an :class:`~opensearchpy.AsyncSearch` instance that will search
|
Create an :class:`~opensearchpy.AsyncSearch` instance that will search
|
||||||
over this ``Document``.
|
over this ``Document``.
|
||||||
@@ -142,9 +140,9 @@ class AsyncDocument(ObjectBase):
|
|||||||
@classmethod
|
@classmethod
|
||||||
async def get( # type: ignore
|
async def get( # type: ignore
|
||||||
cls,
|
cls,
|
||||||
id: str,
|
id: Any,
|
||||||
using: Optional[AsyncOpenSearch] = None,
|
using: Any = None,
|
||||||
index: Optional[str] = None,
|
index: Any = None,
|
||||||
**kwargs: Any,
|
**kwargs: Any,
|
||||||
) -> Any:
|
) -> Any:
|
||||||
"""
|
"""
|
||||||
@@ -189,7 +187,7 @@ class AsyncDocument(ObjectBase):
|
|||||||
@classmethod
|
@classmethod
|
||||||
async def mget(
|
async def mget(
|
||||||
cls,
|
cls,
|
||||||
docs: Sequence[str],
|
docs: Any,
|
||||||
using: Optional[AsyncOpenSearch] = None,
|
using: Optional[AsyncOpenSearch] = None,
|
||||||
index: Optional[str] = None,
|
index: Optional[str] = None,
|
||||||
raise_on_error: Optional[bool] = True,
|
raise_on_error: Optional[bool] = True,
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ class AsyncIndexTemplate(object):
|
|||||||
|
|
||||||
|
|
||||||
class AsyncIndex(object):
|
class AsyncIndex(object):
|
||||||
def __init__(self, name: Any, using: str = "default") -> None:
|
def __init__(self, name: Any, using: Any = "default") -> None:
|
||||||
"""
|
"""
|
||||||
:arg name: name of the index
|
:arg name: name of the index
|
||||||
:arg using: connection alias to use, defaults to ``'default'``
|
:arg using: connection alias to use, defaults to ``'default'``
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ class AsyncConnection(Connection):
|
|||||||
|
|
||||||
|
|
||||||
class AIOHttpConnection(AsyncConnection):
|
class AIOHttpConnection(AsyncConnection):
|
||||||
session: Optional[aiohttp.ClientSession]
|
session: aiohttp.ClientSession
|
||||||
ssl_assert_fingerprint: Optional[str]
|
ssl_assert_fingerprint: Optional[str]
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ import base64
|
|||||||
import weakref
|
import weakref
|
||||||
from datetime import date, datetime
|
from datetime import date, datetime
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
from typing import Any, Callable
|
from typing import Any, Callable, Optional
|
||||||
|
|
||||||
from opensearchpy.serializer import Serializer
|
from opensearchpy.serializer import Serializer
|
||||||
|
|
||||||
@@ -185,17 +185,17 @@ def query_params(*opensearch_query_params: Any) -> Callable: # type: ignore
|
|||||||
return _wrapper
|
return _wrapper
|
||||||
|
|
||||||
|
|
||||||
def _bulk_body(serializer: Serializer, body: str) -> str:
|
def _bulk_body(serializer: Optional[Serializer], body: Any) -> Any:
|
||||||
# if not passed in a string, serialize items and join by newline
|
# if not passed in a string, serialize items and join by newline
|
||||||
if not isinstance(body, string_types):
|
if not isinstance(body, string_types):
|
||||||
body = "\n".join(map(serializer.dumps, body))
|
body = "\n".join(map(serializer.dumps, body)) # type: ignore
|
||||||
|
|
||||||
# bulk body must end with a newline
|
# bulk body must end with a newline
|
||||||
if isinstance(body, bytes):
|
if isinstance(body, bytes):
|
||||||
if not body.endswith(b"\n"):
|
if not body.endswith(b"\n"):
|
||||||
body += b"\n"
|
body += b"\n"
|
||||||
elif isinstance(body, string_types) and not body.endswith("\n"):
|
elif isinstance(body, string_types) and not body.endswith("\n"): # type: ignore
|
||||||
body += "\n"
|
body += "\n" # type: ignore
|
||||||
|
|
||||||
return body
|
return body
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ from opensearchpy.serializer import serializer
|
|||||||
|
|
||||||
|
|
||||||
class AsyncConnections(object):
|
class AsyncConnections(object):
|
||||||
|
_conns: Any
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Class responsible for holding connections to different clusters. Used as a
|
Class responsible for holding connections to different clusters. Used as a
|
||||||
singleton in this module.
|
singleton in this module.
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ class ConnectionPool(object):
|
|||||||
connections: Any
|
connections: Any
|
||||||
orig_connections: Tuple[Connection, ...]
|
orig_connections: Tuple[Connection, ...]
|
||||||
dead: Any
|
dead: Any
|
||||||
dead_count: Dict[Connection, int]
|
dead_count: Dict[Any, int]
|
||||||
dead_timeout: float
|
dead_timeout: float
|
||||||
timeout_cutoff: int
|
timeout_cutoff: int
|
||||||
selector: Any
|
selector: Any
|
||||||
@@ -173,7 +173,7 @@ class ConnectionPool(object):
|
|||||||
|
|
||||||
self.selector = selector_class(dict(connections)) # type: ignore
|
self.selector = selector_class(dict(connections)) # type: ignore
|
||||||
|
|
||||||
def mark_dead(self, connection: Connection, now: Optional[float] = None) -> None:
|
def mark_dead(self, connection: Any, now: Optional[float] = None) -> None:
|
||||||
"""
|
"""
|
||||||
Mark the connection as dead (failed). Remove it from the live pool and
|
Mark the connection as dead (failed). Remove it from the live pool and
|
||||||
put it on a timeout.
|
put it on a timeout.
|
||||||
@@ -203,7 +203,7 @@ class ConnectionPool(object):
|
|||||||
timeout,
|
timeout,
|
||||||
)
|
)
|
||||||
|
|
||||||
def mark_live(self, connection: Connection) -> None:
|
def mark_live(self, connection: Any) -> None:
|
||||||
"""
|
"""
|
||||||
Mark connection as healthy after a resurrection. Resets the fail
|
Mark connection as healthy after a resurrection. Resets the fail
|
||||||
counter for the connection.
|
counter for the connection.
|
||||||
|
|||||||
@@ -503,12 +503,12 @@ def parallel_bulk(
|
|||||||
def scan(
|
def scan(
|
||||||
client: Any,
|
client: Any,
|
||||||
query: Any = None,
|
query: Any = None,
|
||||||
scroll: str = "5m",
|
scroll: Optional[str] = "5m",
|
||||||
raise_on_error: bool = True,
|
raise_on_error: Optional[bool] = True,
|
||||||
preserve_order: bool = False,
|
preserve_order: Optional[bool] = False,
|
||||||
size: int = 1000,
|
size: Optional[int] = 1000,
|
||||||
request_timeout: Optional[float] = None,
|
request_timeout: Optional[float] = None,
|
||||||
clear_scroll: bool = True,
|
clear_scroll: Optional[bool] = True,
|
||||||
scroll_kwargs: Any = None,
|
scroll_kwargs: Any = None,
|
||||||
**kwargs: Any
|
**kwargs: Any
|
||||||
) -> Any:
|
) -> Any:
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
# Modifications Copyright OpenSearch Contributors. See
|
# Modifications Copyright OpenSearch Contributors. See
|
||||||
# GitHub history for details.
|
# GitHub history for details.
|
||||||
|
|
||||||
from typing import Dict, Union
|
from typing import Any, Dict, Optional, Union
|
||||||
|
|
||||||
|
|
||||||
class AWSV4SignerAsyncAuth:
|
class AWSV4SignerAsyncAuth:
|
||||||
@@ -16,7 +16,7 @@ class AWSV4SignerAsyncAuth:
|
|||||||
AWS V4 Request Signer for Async Requests.
|
AWS V4 Request Signer for Async Requests.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, credentials, region: str, service: str = "es") -> None: # type: ignore
|
def __init__(self, credentials: Any, region: str, service: str = "es") -> None:
|
||||||
if not credentials:
|
if not credentials:
|
||||||
raise ValueError("Credentials cannot be empty")
|
raise ValueError("Credentials cannot be empty")
|
||||||
self.credentials = credentials
|
self.credentials = credentials
|
||||||
@@ -30,12 +30,20 @@ class AWSV4SignerAsyncAuth:
|
|||||||
self.service = service
|
self.service = service
|
||||||
|
|
||||||
def __call__(
|
def __call__(
|
||||||
self, method: str, url: str, query_string: str, body: Union[str, bytes]
|
self,
|
||||||
|
method: str,
|
||||||
|
url: str,
|
||||||
|
query_string: Optional[str] = None,
|
||||||
|
body: Optional[Union[str, bytes]] = None,
|
||||||
) -> Dict[str, str]:
|
) -> Dict[str, str]:
|
||||||
return self._sign_request(method, url, query_string, body)
|
return self._sign_request(method, url, query_string, body)
|
||||||
|
|
||||||
def _sign_request(
|
def _sign_request(
|
||||||
self, method: str, url: str, query_string: str, body: Union[str, bytes]
|
self,
|
||||||
|
method: str,
|
||||||
|
url: str,
|
||||||
|
query_string: Optional[str],
|
||||||
|
body: Optional[Union[str, bytes]],
|
||||||
) -> Dict[str, str]:
|
) -> Dict[str, str]:
|
||||||
"""
|
"""
|
||||||
This method helps in signing the request by injecting the required headers.
|
This method helps in signing the request by injecting the required headers.
|
||||||
|
|||||||
@@ -268,9 +268,7 @@ class Date(Field):
|
|||||||
name: Optional[str] = "date"
|
name: Optional[str] = "date"
|
||||||
_coerce: bool = True
|
_coerce: bool = True
|
||||||
|
|
||||||
def __init__(
|
def __init__(self, default_timezone: Any = None, *args: Any, **kwargs: Any) -> None:
|
||||||
self, default_timezone: None = None, *args: Any, **kwargs: Any
|
|
||||||
) -> None:
|
|
||||||
"""
|
"""
|
||||||
:arg default_timezone: timezone that will be automatically used for tz-naive values
|
:arg default_timezone: timezone that will be automatically used for tz-naive values
|
||||||
May be instance of `datetime.tzinfo` or string containing TZ offset
|
May be instance of `datetime.tzinfo` or string containing TZ offset
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ class IndexTemplate(object):
|
|||||||
|
|
||||||
|
|
||||||
class Index(object):
|
class Index(object):
|
||||||
def __init__(self, name: Any, using: str = "default") -> None:
|
def __init__(self, name: Any, using: Any = "default") -> None:
|
||||||
"""
|
"""
|
||||||
:arg name: name of the index
|
:arg name: name of the index
|
||||||
:arg using: connection alias to use, defaults to ``'default'``
|
:arg using: connection alias to use, defaults to ``'default'``
|
||||||
|
|||||||
@@ -31,12 +31,11 @@ from typing import Any, Optional
|
|||||||
|
|
||||||
# 'SF' looks unused but the test suite assumes it's available
|
# 'SF' looks unused but the test suite assumes it's available
|
||||||
# from this module so others are liable to do so as well.
|
# from this module so others are liable to do so as well.
|
||||||
from ..helpers.function import SF # noqa: F401
|
from ..helpers.function import SF, ScoreFunction
|
||||||
from ..helpers.function import ScoreFunction
|
|
||||||
from .utils import DslBase
|
from .utils import DslBase
|
||||||
|
|
||||||
|
|
||||||
def Q(name_or_query: str = "match_all", **params: Any) -> Any:
|
def Q(name_or_query: Any = "match_all", **params: Any) -> Any:
|
||||||
# {"match": {"title": "python"}}
|
# {"match": {"title": "python"}}
|
||||||
if isinstance(name_or_query, collections_abc.Mapping):
|
if isinstance(name_or_query, collections_abc.Mapping):
|
||||||
if params:
|
if params:
|
||||||
@@ -521,3 +520,6 @@ class ParentId(Query):
|
|||||||
|
|
||||||
class Wrapper(Query):
|
class Wrapper(Query):
|
||||||
name = "wrapper"
|
name = "wrapper"
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = ["SF"]
|
||||||
|
|||||||
@@ -864,3 +864,6 @@ class MultiSearch(Request):
|
|||||||
self._response = out
|
self._response = out
|
||||||
|
|
||||||
return self._response
|
return self._response
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = ["Q"]
|
||||||
|
|||||||
@@ -26,11 +26,9 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
|
||||||
# type: ignore
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
from typing import Any, Tuple
|
from typing import Any
|
||||||
from unittest import SkipTest, TestCase
|
from unittest import SkipTest, TestCase
|
||||||
|
|
||||||
import opensearchpy.client
|
import opensearchpy.client
|
||||||
@@ -52,7 +50,7 @@ def get_test_client(nowait: bool = False, **kwargs: Any) -> OpenSearch:
|
|||||||
)
|
)
|
||||||
|
|
||||||
kw.update(kwargs)
|
kw.update(kwargs)
|
||||||
client = OpenSearch(OPENSEARCH_URL, **kw)
|
client = OpenSearch(OPENSEARCH_URL, **kw) # type: ignore
|
||||||
|
|
||||||
# wait for yellow status
|
# wait for yellow status
|
||||||
for _ in range(1 if nowait else 100):
|
for _ in range(1 if nowait else 100):
|
||||||
@@ -67,6 +65,8 @@ def get_test_client(nowait: bool = False, **kwargs: Any) -> OpenSearch:
|
|||||||
|
|
||||||
|
|
||||||
class OpenSearchTestCase(TestCase):
|
class OpenSearchTestCase(TestCase):
|
||||||
|
client: Any
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _get_client() -> OpenSearch:
|
def _get_client() -> OpenSearch:
|
||||||
return get_test_client()
|
return get_test_client()
|
||||||
@@ -86,20 +86,20 @@ class OpenSearchTestCase(TestCase):
|
|||||||
)
|
)
|
||||||
self.client.indices.delete_template(name="*", ignore=404)
|
self.client.indices.delete_template(name="*", ignore=404)
|
||||||
|
|
||||||
def opensearch_version(self) -> Tuple[int, ...]:
|
def opensearch_version(self) -> Any:
|
||||||
if not hasattr(self, "_opensearch_version"):
|
if not hasattr(self, "_opensearch_version"):
|
||||||
self._opensearch_version = opensearch_version(self.client)
|
self._opensearch_version = opensearch_version(self.client)
|
||||||
return self._opensearch_version
|
return self._opensearch_version
|
||||||
|
|
||||||
|
|
||||||
def _get_version(version_string: str) -> Tuple[int, ...]:
|
def _get_version(version_string: str) -> Any:
|
||||||
if "." not in version_string:
|
if "." not in version_string:
|
||||||
return ()
|
return ()
|
||||||
version = version_string.strip().split(".")
|
version = version_string.strip().split(".")
|
||||||
return tuple(int(v) if v.isdigit() else 999 for v in version)
|
return tuple(int(v) if v.isdigit() else 999 for v in version)
|
||||||
|
|
||||||
|
|
||||||
def opensearch_version(client: opensearchpy.client.OpenSearch) -> Tuple[int, int, int]:
|
def opensearch_version(client: opensearchpy.client.OpenSearch) -> Any:
|
||||||
return _get_version(client.info()["version"]["number"])
|
return _get_version(client.info()["version"]["number"])
|
||||||
|
|
||||||
|
|
||||||
@@ -111,3 +111,5 @@ else:
|
|||||||
verify_certs=False,
|
verify_certs=False,
|
||||||
)
|
)
|
||||||
OPENSEARCH_VERSION = opensearch_version(client)
|
OPENSEARCH_VERSION = opensearch_version(client)
|
||||||
|
|
||||||
|
__all__ = ["OpenSearchTestCase"]
|
||||||
|
|||||||
@@ -284,7 +284,7 @@ class DslBase(object):
|
|||||||
"DSL class `{}` does not exist in {}.".format(name, cls._type_name)
|
"DSL class `{}` does not exist in {}.".format(name, cls._type_name)
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, _expand__to_dot: bool = EXPAND__TO_DOT, **params: Any) -> None:
|
def __init__(self, _expand__to_dot: Any = EXPAND__TO_DOT, **params: Any) -> None:
|
||||||
self._params = {}
|
self._params = {}
|
||||||
for pname, pvalue in iteritems(params):
|
for pname, pvalue in iteritems(params):
|
||||||
if "__" in pname and _expand__to_dot:
|
if "__" in pname and _expand__to_dot:
|
||||||
@@ -438,6 +438,8 @@ class HitMeta(AttrDict):
|
|||||||
|
|
||||||
|
|
||||||
class ObjectBase(AttrDict):
|
class ObjectBase(AttrDict):
|
||||||
|
_doc_type: Any
|
||||||
|
|
||||||
def __init__(self, meta: Any = None, **kwargs: Any) -> None:
|
def __init__(self, meta: Any = None, **kwargs: Any) -> None:
|
||||||
meta = meta or {}
|
meta = meta or {}
|
||||||
for k in list(kwargs):
|
for k in list(kwargs):
|
||||||
|
|||||||
@@ -373,7 +373,7 @@ class Transport(object):
|
|||||||
method: str,
|
method: str,
|
||||||
url: str,
|
url: str,
|
||||||
params: Optional[Mapping[str, Any]] = None,
|
params: Optional[Mapping[str, Any]] = None,
|
||||||
body: Optional[bytes] = None,
|
body: Any = None,
|
||||||
timeout: Optional[Union[int, float]] = None,
|
timeout: Optional[Union[int, float]] = None,
|
||||||
ignore: Collection[int] = (),
|
ignore: Collection[int] = (),
|
||||||
headers: Optional[Mapping[str, str]] = None,
|
headers: Optional[Mapping[str, str]] = None,
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from opensearchpy import OpenSearch
|
from opensearchpy import OpenSearch
|
||||||
|
|
||||||
@@ -45,7 +46,7 @@ if not client.indices.exists(index_name):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# index data
|
# index data
|
||||||
data = []
|
data: Any = []
|
||||||
for i in range(100):
|
for i in range(100):
|
||||||
data.append({"index": {"_index": index_name, "_id": i}})
|
data.append({"index": {"_index": index_name, "_id": i}})
|
||||||
data.append({"value": i})
|
data.append({"value": i})
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import asyncio
|
|||||||
from opensearchpy import AsyncOpenSearch
|
from opensearchpy import AsyncOpenSearch
|
||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main() -> None:
|
||||||
# connect to OpenSearch
|
# connect to OpenSearch
|
||||||
host = "localhost"
|
host = "localhost"
|
||||||
port = 9200
|
port = 9200
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import asyncio
|
|||||||
from opensearchpy import AsyncOpenSearch
|
from opensearchpy import AsyncOpenSearch
|
||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main() -> None:
|
||||||
# connect to OpenSearch
|
# connect to OpenSearch
|
||||||
host = "localhost"
|
host = "localhost"
|
||||||
port = 9200
|
port = 9200
|
||||||
@@ -18,7 +18,7 @@ import random
|
|||||||
from opensearchpy import AsyncHttpConnection, AsyncOpenSearch, helpers
|
from opensearchpy import AsyncHttpConnection, AsyncOpenSearch, helpers
|
||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main() -> None:
|
||||||
# connect to an instance of OpenSearch
|
# connect to an instance of OpenSearch
|
||||||
host = os.getenv("HOST", default="localhost")
|
host = os.getenv("HOST", default="localhost")
|
||||||
port = int(os.getenv("PORT", 9200))
|
port = int(os.getenv("PORT", 9200))
|
||||||
|
|||||||
@@ -11,10 +11,11 @@
|
|||||||
import json
|
import json
|
||||||
import threading
|
import threading
|
||||||
from http.server import BaseHTTPRequestHandler, HTTPServer
|
from http.server import BaseHTTPRequestHandler, HTTPServer
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
|
||||||
class TestHTTPRequestHandler(BaseHTTPRequestHandler):
|
class TestHTTPRequestHandler(BaseHTTPRequestHandler):
|
||||||
def do_GET(self):
|
def do_GET(self) -> None:
|
||||||
headers = self.headers
|
headers = self.headers
|
||||||
|
|
||||||
if self.path == "/redirect":
|
if self.path == "/redirect":
|
||||||
@@ -40,6 +41,7 @@ class TestHTTPRequestHandler(BaseHTTPRequestHandler):
|
|||||||
|
|
||||||
class TestHTTPServer(HTTPServer):
|
class TestHTTPServer(HTTPServer):
|
||||||
__test__ = False
|
__test__ = False
|
||||||
|
_server_thread: Any
|
||||||
|
|
||||||
def __init__(self, host: str = "localhost", port: int = 8080) -> None:
|
def __init__(self, host: str = "localhost", port: int = 8080) -> None:
|
||||||
super().__init__((host, port), TestHTTPRequestHandler)
|
super().__init__((host, port), TestHTTPRequestHandler)
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ import subprocess
|
|||||||
import sys
|
import sys
|
||||||
from os import environ
|
from os import environ
|
||||||
from os.path import abspath, dirname, exists, join, pardir
|
from os.path import abspath, dirname, exists, join, pardir
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
|
||||||
def fetch_opensearch_repo() -> None:
|
def fetch_opensearch_repo() -> None:
|
||||||
@@ -88,8 +89,8 @@ def fetch_opensearch_repo() -> None:
|
|||||||
subprocess.check_call("cd %s && git fetch origin %s" % (repo_path, sha), shell=True)
|
subprocess.check_call("cd %s && git fetch origin %s" % (repo_path, sha), shell=True)
|
||||||
|
|
||||||
|
|
||||||
def run_all(argv: None = None) -> None:
|
def run_all(argv: Any = None) -> None:
|
||||||
sys.exitfunc = lambda: sys.stderr.write("Shutting down....\n")
|
sys.exitfunc = lambda: sys.stderr.write("Shutting down....\n") # type: ignore
|
||||||
# fetch yaml tests anywhere that's not GitHub Actions
|
# fetch yaml tests anywhere that's not GitHub Actions
|
||||||
if "GITHUB_ACTION" not in environ:
|
if "GITHUB_ACTION" not in environ:
|
||||||
fetch_opensearch_repo()
|
fetch_opensearch_repo()
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import json
|
|||||||
import ssl
|
import ssl
|
||||||
import warnings
|
import warnings
|
||||||
from platform import python_version
|
from platform import python_version
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import aiohttp
|
import aiohttp
|
||||||
import pytest
|
import pytest
|
||||||
@@ -52,29 +53,29 @@ pytestmark: MarkDecorator = pytest.mark.asyncio
|
|||||||
class TestAIOHttpConnection:
|
class TestAIOHttpConnection:
|
||||||
async def _get_mock_connection(
|
async def _get_mock_connection(
|
||||||
self,
|
self,
|
||||||
connection_params={},
|
connection_params: Any = {},
|
||||||
response_code: int = 200,
|
response_code: int = 200,
|
||||||
response_body: bytes = b"{}",
|
response_body: bytes = b"{}",
|
||||||
response_headers={},
|
response_headers: Any = {},
|
||||||
):
|
) -> Any:
|
||||||
con = AIOHttpConnection(**connection_params)
|
con = AIOHttpConnection(**connection_params)
|
||||||
await con._create_aiohttp_session()
|
await con._create_aiohttp_session()
|
||||||
|
|
||||||
def _dummy_request(*args, **kwargs):
|
def _dummy_request(*args: Any, **kwargs: Any) -> Any:
|
||||||
class DummyResponse:
|
class DummyResponse:
|
||||||
async def __aenter__(self, *_, **__):
|
async def __aenter__(self, *_: Any, **__: Any) -> Any:
|
||||||
return self
|
return self
|
||||||
|
|
||||||
async def __aexit__(self, *_, **__):
|
async def __aexit__(self, *_: Any, **__: Any) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
async def text(self):
|
async def text(self) -> Any:
|
||||||
return response_body.decode("utf-8", "surrogatepass")
|
return response_body.decode("utf-8", "surrogatepass")
|
||||||
|
|
||||||
dummy_response = DummyResponse()
|
dummy_response: Any = DummyResponse()
|
||||||
dummy_response.headers = CIMultiDict(**response_headers)
|
dummy_response.headers = CIMultiDict(**response_headers)
|
||||||
dummy_response.status = response_code
|
dummy_response.status = response_code
|
||||||
_dummy_request.call_args = (args, kwargs)
|
_dummy_request.call_args = (args, kwargs) # type: ignore
|
||||||
return dummy_response
|
return dummy_response
|
||||||
|
|
||||||
con.session.request = _dummy_request
|
con.session.request = _dummy_request
|
||||||
@@ -231,6 +232,7 @@ class TestAIOHttpConnection:
|
|||||||
assert w == [], str([x.message for x in w])
|
assert w == [], str([x.message for x in w])
|
||||||
|
|
||||||
async def test_warns_if_using_non_default_ssl_kwargs_with_ssl_context(self) -> None:
|
async def test_warns_if_using_non_default_ssl_kwargs_with_ssl_context(self) -> None:
|
||||||
|
kwargs: Any
|
||||||
for kwargs in (
|
for kwargs in (
|
||||||
{"ssl_show_warn": False},
|
{"ssl_show_warn": False},
|
||||||
{"ssl_show_warn": True},
|
{"ssl_show_warn": True},
|
||||||
@@ -253,26 +255,28 @@ class TestAIOHttpConnection:
|
|||||||
)
|
)
|
||||||
|
|
||||||
@patch("ssl.SSLContext.load_verify_locations")
|
@patch("ssl.SSLContext.load_verify_locations")
|
||||||
async def test_uses_given_ca_certs(self, load_verify_locations, tmp_path) -> None:
|
async def test_uses_given_ca_certs(
|
||||||
|
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()
|
||||||
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))
|
load_verify_locations.assert_called_once_with(cafile=str(path))
|
||||||
|
|
||||||
@patch("ssl.SSLContext.load_verify_locations")
|
@patch("ssl.SSLContext.load_verify_locations")
|
||||||
async def test_uses_default_ca_certs(self, load_verify_locations) -> None:
|
async def test_uses_default_ca_certs(self, load_verify_locations: Any) -> None:
|
||||||
AIOHttpConnection(use_ssl=True)
|
AIOHttpConnection(use_ssl=True)
|
||||||
load_verify_locations.assert_called_once_with(
|
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.load_verify_locations")
|
||||||
async def test_uses_no_ca_certs(self, load_verify_locations) -> None:
|
async def test_uses_no_ca_certs(self, load_verify_locations: Any) -> None:
|
||||||
AIOHttpConnection(use_ssl=True, verify_certs=False)
|
AIOHttpConnection(use_ssl=True, verify_certs=False)
|
||||||
load_verify_locations.assert_not_called()
|
load_verify_locations.assert_not_called()
|
||||||
|
|
||||||
async def test_trust_env(self) -> None:
|
async def test_trust_env(self) -> None:
|
||||||
con = AIOHttpConnection(trust_env=True)
|
con: Any = AIOHttpConnection(trust_env=True)
|
||||||
await con._create_aiohttp_session()
|
await con._create_aiohttp_session()
|
||||||
|
|
||||||
assert con._trust_env is True
|
assert con._trust_env is True
|
||||||
@@ -286,7 +290,7 @@ class TestAIOHttpConnection:
|
|||||||
assert con.session.trust_env is False
|
assert con.session.trust_env is False
|
||||||
|
|
||||||
@patch("opensearchpy.connection.base.logger")
|
@patch("opensearchpy.connection.base.logger")
|
||||||
async def test_uncompressed_body_logged(self, logger) -> None:
|
async def test_uncompressed_body_logged(self, logger: Any) -> None:
|
||||||
con = await self._get_mock_connection(connection_params={"http_compress": True})
|
con = await self._get_mock_connection(connection_params={"http_compress": True})
|
||||||
await con.perform_request("GET", "/", body=b'{"example": "body"}')
|
await con.perform_request("GET", "/", body=b'{"example": "body"}')
|
||||||
|
|
||||||
@@ -302,11 +306,11 @@ class TestAIOHttpConnection:
|
|||||||
status, headers, data = await con.perform_request("GET", "/")
|
status, headers, data = await con.perform_request("GET", "/")
|
||||||
assert u"你好\uda6a" == data # fmt: skip
|
assert u"你好\uda6a" == data # fmt: skip
|
||||||
|
|
||||||
@pytest.mark.parametrize("exception_cls", reraise_exceptions)
|
@pytest.mark.parametrize("exception_cls", reraise_exceptions) # type: ignore
|
||||||
async def test_recursion_error_reraised(self, exception_cls) -> None:
|
async def test_recursion_error_reraised(self, exception_cls: Any) -> None:
|
||||||
conn = AIOHttpConnection()
|
conn = AIOHttpConnection()
|
||||||
|
|
||||||
def request_raise(*_, **__):
|
def request_raise(*_: Any, **__: Any) -> Any:
|
||||||
raise exception_cls("Wasn't modified!")
|
raise exception_cls("Wasn't modified!")
|
||||||
|
|
||||||
await conn._create_aiohttp_session()
|
await conn._create_aiohttp_session()
|
||||||
@@ -334,6 +338,8 @@ class TestAIOHttpConnection:
|
|||||||
class TestConnectionHttpServer:
|
class TestConnectionHttpServer:
|
||||||
"""Tests the HTTP connection implementations against a live server E2E"""
|
"""Tests the HTTP connection implementations against a live server E2E"""
|
||||||
|
|
||||||
|
server: Any
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setup_class(cls) -> None:
|
def setup_class(cls) -> None:
|
||||||
# Start server
|
# Start server
|
||||||
@@ -345,7 +351,7 @@ class TestConnectionHttpServer:
|
|||||||
# Stop server
|
# Stop server
|
||||||
cls.server.stop()
|
cls.server.stop()
|
||||||
|
|
||||||
async def httpserver(self, conn, **kwargs):
|
async def httpserver(self, conn: Any, **kwargs: Any) -> Any:
|
||||||
status, headers, data = await conn.perform_request("GET", "/", **kwargs)
|
status, headers, data = await conn.perform_request("GET", "/", **kwargs)
|
||||||
data = json.loads(data)
|
data = json.loads(data)
|
||||||
return (status, data)
|
return (status, data)
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
# GitHub history for details.
|
# GitHub history for details.
|
||||||
|
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from _pytest.mark.structures import MarkDecorator
|
from _pytest.mark.structures import MarkDecorator
|
||||||
from mock import Mock
|
from mock import Mock
|
||||||
@@ -19,18 +21,18 @@ from opensearchpy.connection.async_connections import add_connection, async_conn
|
|||||||
pytestmark: MarkDecorator = pytest.mark.asyncio
|
pytestmark: MarkDecorator = pytest.mark.asyncio
|
||||||
|
|
||||||
|
|
||||||
@fixture
|
@fixture # type: ignore
|
||||||
async def mock_client(dummy_response):
|
async def mock_client(dummy_response: Any) -> Any:
|
||||||
client = Mock()
|
client = Mock()
|
||||||
client.search.return_value = dummy_response
|
client.search.return_value = dummy_response
|
||||||
await add_connection("mock", client)
|
await add_connection("mock", client)
|
||||||
yield client
|
yield client
|
||||||
async_connections._conn = {}
|
async_connections._conns = {}
|
||||||
async_connections._kwargs = {}
|
async_connections._kwargs = {}
|
||||||
|
|
||||||
|
|
||||||
@fixture
|
@fixture # type: ignore
|
||||||
def dummy_response():
|
def dummy_response() -> Any:
|
||||||
return {
|
return {
|
||||||
"_shards": {"failed": 0, "successful": 10, "total": 10},
|
"_shards": {"failed": 0, "successful": 10, "total": 10},
|
||||||
"hits": {
|
"hits": {
|
||||||
@@ -78,8 +80,8 @@ def dummy_response():
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@fixture
|
@fixture # type: ignore
|
||||||
def aggs_search():
|
def aggs_search() -> Any:
|
||||||
from opensearchpy._async.helpers.search import AsyncSearch
|
from opensearchpy._async.helpers.search import AsyncSearch
|
||||||
|
|
||||||
s = AsyncSearch(index="flat-git")
|
s = AsyncSearch(index="flat-git")
|
||||||
@@ -93,8 +95,8 @@ def aggs_search():
|
|||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
||||||
@fixture
|
@fixture # type: ignore
|
||||||
def aggs_data():
|
def aggs_data() -> Any:
|
||||||
return {
|
return {
|
||||||
"took": 4,
|
"took": 4,
|
||||||
"timed_out": False,
|
"timed_out": False,
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import ipaddress
|
|||||||
import pickle
|
import pickle
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from hashlib import sha256
|
from hashlib import sha256
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from _pytest.mark.structures import MarkDecorator
|
from _pytest.mark.structures import MarkDecorator
|
||||||
@@ -31,25 +32,25 @@ pytestmark: MarkDecorator = pytest.mark.asyncio
|
|||||||
|
|
||||||
|
|
||||||
class MyInner(InnerDoc):
|
class MyInner(InnerDoc):
|
||||||
old_field = field.Text()
|
old_field: Any = field.Text()
|
||||||
|
|
||||||
|
|
||||||
class MyDoc(document.AsyncDocument):
|
class MyDoc(document.AsyncDocument):
|
||||||
title = field.Keyword()
|
title: Any = field.Keyword()
|
||||||
name = field.Text()
|
name: Any = field.Text()
|
||||||
created_at = field.Date()
|
created_at: Any = field.Date()
|
||||||
inner = field.Object(MyInner)
|
inner: Any = field.Object(MyInner)
|
||||||
|
|
||||||
|
|
||||||
class MySubDoc(MyDoc):
|
class MySubDoc(MyDoc):
|
||||||
name = field.Keyword()
|
name: Any = field.Keyword()
|
||||||
|
|
||||||
class Index:
|
class Index:
|
||||||
name = "default-index"
|
name = "default-index"
|
||||||
|
|
||||||
|
|
||||||
class MyDoc2(document.AsyncDocument):
|
class MyDoc2(document.AsyncDocument):
|
||||||
extra = field.Long()
|
extra: Any = field.Long()
|
||||||
|
|
||||||
|
|
||||||
class MyMultiSubDoc(MyDoc2, MySubDoc):
|
class MyMultiSubDoc(MyDoc2, MySubDoc):
|
||||||
@@ -57,19 +58,19 @@ class MyMultiSubDoc(MyDoc2, MySubDoc):
|
|||||||
|
|
||||||
|
|
||||||
class Comment(InnerDoc):
|
class Comment(InnerDoc):
|
||||||
title = field.Text()
|
title: Any = field.Text()
|
||||||
tags = field.Keyword(multi=True)
|
tags: Any = field.Keyword(multi=True)
|
||||||
|
|
||||||
|
|
||||||
class DocWithNested(document.AsyncDocument):
|
class DocWithNested(document.AsyncDocument):
|
||||||
comments = field.Nested(Comment)
|
comments: Any = field.Nested(Comment)
|
||||||
|
|
||||||
class Index:
|
class Index:
|
||||||
name = "test-doc-with-nested"
|
name = "test-doc-with-nested"
|
||||||
|
|
||||||
|
|
||||||
class SimpleCommit(document.AsyncDocument):
|
class SimpleCommit(document.AsyncDocument):
|
||||||
files = field.Text(multi=True)
|
files: Any = field.Text(multi=True)
|
||||||
|
|
||||||
class Index:
|
class Index:
|
||||||
name = "test-git"
|
name = "test-git"
|
||||||
@@ -80,48 +81,54 @@ class Secret(str):
|
|||||||
|
|
||||||
|
|
||||||
class SecretField(field.CustomField):
|
class SecretField(field.CustomField):
|
||||||
builtin_type = "text"
|
builtin_type: Any = "text"
|
||||||
|
|
||||||
def _serialize(self, data):
|
def _serialize(self, data: Any) -> Any:
|
||||||
return codecs.encode(data, "rot_13")
|
return codecs.encode(data, "rot_13")
|
||||||
|
|
||||||
def _deserialize(self, data):
|
def _deserialize(self, data: Any) -> Any:
|
||||||
if isinstance(data, Secret):
|
if isinstance(data, Secret):
|
||||||
return data
|
return data
|
||||||
return Secret(codecs.decode(data, "rot_13"))
|
return Secret(codecs.decode(data, "rot_13"))
|
||||||
|
|
||||||
|
|
||||||
class SecretDoc(document.AsyncDocument):
|
class SecretDoc(document.AsyncDocument):
|
||||||
title = SecretField(index="no")
|
title: Any = SecretField(index="no")
|
||||||
|
|
||||||
class Index:
|
class Index:
|
||||||
name = "test-secret-doc"
|
name = "test-secret-doc"
|
||||||
|
|
||||||
|
|
||||||
class NestedSecret(document.AsyncDocument):
|
class NestedSecret(document.AsyncDocument):
|
||||||
secrets = field.Nested(SecretDoc)
|
secrets: Any = field.Nested(SecretDoc)
|
||||||
|
|
||||||
class Index:
|
class Index:
|
||||||
name = "test-nested-secret"
|
name = "test-nested-secret"
|
||||||
|
|
||||||
|
_index: Any
|
||||||
|
|
||||||
|
|
||||||
class OptionalObjectWithRequiredField(document.AsyncDocument):
|
class OptionalObjectWithRequiredField(document.AsyncDocument):
|
||||||
comments = field.Nested(properties={"title": field.Keyword(required=True)})
|
comments: Any = field.Nested(properties={"title": field.Keyword(required=True)})
|
||||||
|
|
||||||
class Index:
|
class Index:
|
||||||
name = "test-required"
|
name = "test-required"
|
||||||
|
|
||||||
|
_index: Any
|
||||||
|
|
||||||
|
|
||||||
class Host(document.AsyncDocument):
|
class Host(document.AsyncDocument):
|
||||||
ip = field.Ip()
|
ip: Any = field.Ip()
|
||||||
|
|
||||||
class Index:
|
class Index:
|
||||||
name = "test-host"
|
name = "test-host"
|
||||||
|
|
||||||
|
_index: Any
|
||||||
|
|
||||||
|
|
||||||
async def test_range_serializes_properly() -> None:
|
async def test_range_serializes_properly() -> None:
|
||||||
class D(document.AsyncDocument):
|
class D(document.AsyncDocument):
|
||||||
lr = field.LongRange()
|
lr: Any = field.LongRange()
|
||||||
|
|
||||||
d = D(lr=Range(lt=42))
|
d = D(lr=Range(lt=42))
|
||||||
assert 40 in d.lr
|
assert 40 in d.lr
|
||||||
@@ -200,7 +207,7 @@ async def test_assigning_attrlist_to_field() -> None:
|
|||||||
|
|
||||||
|
|
||||||
async def test_optional_inner_objects_are_not_validated_if_missing() -> None:
|
async def test_optional_inner_objects_are_not_validated_if_missing() -> None:
|
||||||
d = OptionalObjectWithRequiredField()
|
d: Any = OptionalObjectWithRequiredField()
|
||||||
|
|
||||||
assert d.full_clean() is None
|
assert d.full_clean() is None
|
||||||
|
|
||||||
@@ -253,13 +260,15 @@ async def test_null_value_for_object() -> None:
|
|||||||
assert d.inner is None
|
assert d.inner is None
|
||||||
|
|
||||||
|
|
||||||
async def test_inherited_doc_types_can_override_index():
|
async def test_inherited_doc_types_can_override_index() -> None:
|
||||||
class MyDocDifferentIndex(MySubDoc):
|
class MyDocDifferentIndex(MySubDoc):
|
||||||
|
_index: Any
|
||||||
|
|
||||||
class Index:
|
class Index:
|
||||||
name = "not-default-index"
|
name: Any = "not-default-index"
|
||||||
settings = {"number_of_replicas": 0}
|
settings: Any = {"number_of_replicas": 0}
|
||||||
aliases = {"a": {}}
|
aliases: Any = {"a": {}}
|
||||||
analyzers = [analyzer("my_analizer", tokenizer="keyword")]
|
analyzers: Any = [analyzer("my_analizer", tokenizer="keyword")]
|
||||||
|
|
||||||
assert MyDocDifferentIndex._index._name == "not-default-index"
|
assert MyDocDifferentIndex._index._name == "not-default-index"
|
||||||
assert MyDocDifferentIndex()._get_index() == "not-default-index"
|
assert MyDocDifferentIndex()._get_index() == "not-default-index"
|
||||||
@@ -285,7 +294,7 @@ async def test_inherited_doc_types_can_override_index():
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async def test_to_dict_with_meta():
|
async def test_to_dict_with_meta() -> None:
|
||||||
d = MySubDoc(title="hello")
|
d = MySubDoc(title="hello")
|
||||||
d.meta.routing = "some-parent"
|
d.meta.routing = "some-parent"
|
||||||
|
|
||||||
@@ -296,7 +305,7 @@ async def test_to_dict_with_meta():
|
|||||||
} == d.to_dict(True)
|
} == d.to_dict(True)
|
||||||
|
|
||||||
|
|
||||||
async def test_to_dict_with_meta_includes_custom_index():
|
async def test_to_dict_with_meta_includes_custom_index() -> None:
|
||||||
d = MySubDoc(title="hello")
|
d = MySubDoc(title="hello")
|
||||||
d.meta.index = "other-index"
|
d.meta.index = "other-index"
|
||||||
|
|
||||||
@@ -340,7 +349,7 @@ async def test_meta_is_accessible_even_on_empty_doc() -> None:
|
|||||||
d.meta
|
d.meta
|
||||||
|
|
||||||
|
|
||||||
async def test_meta_field_mapping():
|
async def test_meta_field_mapping() -> None:
|
||||||
class User(document.AsyncDocument):
|
class User(document.AsyncDocument):
|
||||||
username = field.Text()
|
username = field.Text()
|
||||||
|
|
||||||
@@ -372,17 +381,17 @@ async def test_multi_value_fields() -> None:
|
|||||||
|
|
||||||
async def test_docs_with_properties() -> None:
|
async def test_docs_with_properties() -> None:
|
||||||
class User(document.AsyncDocument):
|
class User(document.AsyncDocument):
|
||||||
pwd_hash = field.Text()
|
pwd_hash: Any = field.Text()
|
||||||
|
|
||||||
def check_password(self, pwd):
|
def check_password(self, pwd: Any) -> Any:
|
||||||
return sha256(pwd).hexdigest() == self.pwd_hash
|
return sha256(pwd).hexdigest() == self.pwd_hash
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def password(self):
|
def password(self) -> Any:
|
||||||
raise AttributeError("readonly")
|
raise AttributeError("readonly")
|
||||||
|
|
||||||
@password.setter
|
@password.setter
|
||||||
def password(self, pwd):
|
def password(self, pwd: Any) -> None:
|
||||||
self.pwd_hash = sha256(pwd).hexdigest()
|
self.pwd_hash = sha256(pwd).hexdigest()
|
||||||
|
|
||||||
u = User(pwd_hash=sha256(b"secret").hexdigest())
|
u = User(pwd_hash=sha256(b"secret").hexdigest())
|
||||||
@@ -424,8 +433,8 @@ async def test_nested_defaults_to_list_and_can_be_updated() -> None:
|
|||||||
assert {"comments": [{"title": "hello World!"}]} == md.to_dict()
|
assert {"comments": [{"title": "hello World!"}]} == md.to_dict()
|
||||||
|
|
||||||
|
|
||||||
async def test_to_dict_is_recursive_and_can_cope_with_multi_values():
|
async def test_to_dict_is_recursive_and_can_cope_with_multi_values() -> None:
|
||||||
md = MyDoc(name=["a", "b", "c"])
|
md: Any = MyDoc(name=["a", "b", "c"])
|
||||||
md.inner = [MyInner(old_field="of1"), MyInner(old_field="of2")]
|
md.inner = [MyInner(old_field="of1"), MyInner(old_field="of2")]
|
||||||
|
|
||||||
assert isinstance(md.inner[0], MyInner)
|
assert isinstance(md.inner[0], MyInner)
|
||||||
@@ -437,12 +446,12 @@ async def test_to_dict_is_recursive_and_can_cope_with_multi_values():
|
|||||||
|
|
||||||
|
|
||||||
async def test_to_dict_ignores_empty_collections() -> None:
|
async def test_to_dict_ignores_empty_collections() -> None:
|
||||||
md = MySubDoc(name="", address={}, count=0, valid=False, tags=[])
|
md: Any = MySubDoc(name="", address={}, count=0, valid=False, tags=[])
|
||||||
|
|
||||||
assert {"name": "", "count": 0, "valid": False} == md.to_dict()
|
assert {"name": "", "count": 0, "valid": False} == md.to_dict()
|
||||||
|
|
||||||
|
|
||||||
async def test_declarative_mapping_definition():
|
async def test_declarative_mapping_definition() -> None:
|
||||||
assert issubclass(MyDoc, document.AsyncDocument)
|
assert issubclass(MyDoc, document.AsyncDocument)
|
||||||
assert hasattr(MyDoc, "_doc_type")
|
assert hasattr(MyDoc, "_doc_type")
|
||||||
assert {
|
assert {
|
||||||
@@ -455,7 +464,7 @@ async def test_declarative_mapping_definition():
|
|||||||
} == MyDoc._doc_type.mapping.to_dict()
|
} == MyDoc._doc_type.mapping.to_dict()
|
||||||
|
|
||||||
|
|
||||||
async def test_you_can_supply_own_mapping_instance():
|
async def test_you_can_supply_own_mapping_instance() -> None:
|
||||||
class MyD(document.AsyncDocument):
|
class MyD(document.AsyncDocument):
|
||||||
title = field.Text()
|
title = field.Text()
|
||||||
|
|
||||||
@@ -469,9 +478,9 @@ async def test_you_can_supply_own_mapping_instance():
|
|||||||
} == MyD._doc_type.mapping.to_dict()
|
} == MyD._doc_type.mapping.to_dict()
|
||||||
|
|
||||||
|
|
||||||
async def test_document_can_be_created_dynamically():
|
async def test_document_can_be_created_dynamically() -> None:
|
||||||
n = datetime.now()
|
n = datetime.now()
|
||||||
md = MyDoc(title="hello")
|
md: Any = MyDoc(title="hello")
|
||||||
md.name = "My Fancy Document!"
|
md.name = "My Fancy Document!"
|
||||||
md.created_at = n
|
md.created_at = n
|
||||||
|
|
||||||
@@ -491,13 +500,13 @@ async def test_document_can_be_created_dynamically():
|
|||||||
|
|
||||||
|
|
||||||
async def test_invalid_date_will_raise_exception() -> None:
|
async def test_invalid_date_will_raise_exception() -> None:
|
||||||
md = MyDoc()
|
md: Any = MyDoc()
|
||||||
md.created_at = "not-a-date"
|
md.created_at = "not-a-date"
|
||||||
with raises(ValidationException):
|
with raises(ValidationException):
|
||||||
md.full_clean()
|
md.full_clean()
|
||||||
|
|
||||||
|
|
||||||
async def test_document_inheritance():
|
async def test_document_inheritance() -> None:
|
||||||
assert issubclass(MySubDoc, MyDoc)
|
assert issubclass(MySubDoc, MyDoc)
|
||||||
assert issubclass(MySubDoc, document.AsyncDocument)
|
assert issubclass(MySubDoc, document.AsyncDocument)
|
||||||
assert hasattr(MySubDoc, "_doc_type")
|
assert hasattr(MySubDoc, "_doc_type")
|
||||||
@@ -511,7 +520,7 @@ async def test_document_inheritance():
|
|||||||
} == MySubDoc._doc_type.mapping.to_dict()
|
} == MySubDoc._doc_type.mapping.to_dict()
|
||||||
|
|
||||||
|
|
||||||
async def test_child_class_can_override_parent():
|
async def test_child_class_can_override_parent() -> None:
|
||||||
class A(document.AsyncDocument):
|
class A(document.AsyncDocument):
|
||||||
o = field.Object(dynamic=False, properties={"a": field.Text()})
|
o = field.Object(dynamic=False, properties={"a": field.Text()})
|
||||||
|
|
||||||
@@ -530,7 +539,7 @@ async def test_child_class_can_override_parent():
|
|||||||
|
|
||||||
|
|
||||||
async def test_meta_fields_are_stored_in_meta_and_ignored_by_to_dict() -> None:
|
async def test_meta_fields_are_stored_in_meta_and_ignored_by_to_dict() -> None:
|
||||||
md = MySubDoc(meta={"id": 42}, name="My First doc!")
|
md: Any = MySubDoc(meta={"id": 42}, name="My First doc!")
|
||||||
|
|
||||||
md.meta.index = "my-index"
|
md.meta.index = "my-index"
|
||||||
assert md.meta.index == "my-index"
|
assert md.meta.index == "my-index"
|
||||||
@@ -539,7 +548,7 @@ async def test_meta_fields_are_stored_in_meta_and_ignored_by_to_dict() -> None:
|
|||||||
assert {"id": 42, "index": "my-index"} == md.meta.to_dict()
|
assert {"id": 42, "index": "my-index"} == md.meta.to_dict()
|
||||||
|
|
||||||
|
|
||||||
async def test_index_inheritance():
|
async def test_index_inheritance() -> None:
|
||||||
assert issubclass(MyMultiSubDoc, MySubDoc)
|
assert issubclass(MyMultiSubDoc, MySubDoc)
|
||||||
assert issubclass(MyMultiSubDoc, MyDoc2)
|
assert issubclass(MyMultiSubDoc, MyDoc2)
|
||||||
assert issubclass(MyMultiSubDoc, document.AsyncDocument)
|
assert issubclass(MyMultiSubDoc, document.AsyncDocument)
|
||||||
@@ -558,31 +567,31 @@ async def test_index_inheritance():
|
|||||||
|
|
||||||
async def test_meta_fields_can_be_set_directly_in_init() -> None:
|
async def test_meta_fields_can_be_set_directly_in_init() -> None:
|
||||||
p = object()
|
p = object()
|
||||||
md = MyDoc(_id=p, title="Hello World!")
|
md: Any = MyDoc(_id=p, title="Hello World!")
|
||||||
|
|
||||||
assert md.meta.id is p
|
assert md.meta.id is p
|
||||||
|
|
||||||
|
|
||||||
async def test_save_no_index(mock_client) -> None:
|
async def test_save_no_index(mock_client: Any) -> None:
|
||||||
md = MyDoc()
|
md: Any = MyDoc()
|
||||||
with raises(ValidationException):
|
with raises(ValidationException):
|
||||||
await md.save(using="mock")
|
await md.save(using="mock")
|
||||||
|
|
||||||
|
|
||||||
async def test_delete_no_index(mock_client) -> None:
|
async def test_delete_no_index(mock_client: Any) -> None:
|
||||||
md = MyDoc()
|
md: Any = MyDoc()
|
||||||
with raises(ValidationException):
|
with raises(ValidationException):
|
||||||
await md.delete(using="mock")
|
await md.delete(using="mock")
|
||||||
|
|
||||||
|
|
||||||
async def test_update_no_fields() -> None:
|
async def test_update_no_fields() -> None:
|
||||||
md = MyDoc()
|
md: Any = MyDoc()
|
||||||
with raises(IllegalOperation):
|
with raises(IllegalOperation):
|
||||||
await md.update()
|
await md.update()
|
||||||
|
|
||||||
|
|
||||||
async def test_search_with_custom_alias_and_index(mock_client) -> None:
|
async def test_search_with_custom_alias_and_index(mock_client: Any) -> None:
|
||||||
search_object = MyDoc.search(
|
search_object: Any = MyDoc.search(
|
||||||
using="staging", index=["custom_index1", "custom_index2"]
|
using="staging", index=["custom_index1", "custom_index2"]
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -590,8 +599,8 @@ async def test_search_with_custom_alias_and_index(mock_client) -> None:
|
|||||||
assert search_object._index == ["custom_index1", "custom_index2"]
|
assert search_object._index == ["custom_index1", "custom_index2"]
|
||||||
|
|
||||||
|
|
||||||
async def test_from_opensearch_respects_underscored_non_meta_fields():
|
async def test_from_opensearch_respects_underscored_non_meta_fields() -> None:
|
||||||
doc = {
|
doc: Any = {
|
||||||
"_index": "test-index",
|
"_index": "test-index",
|
||||||
"_id": "opensearch",
|
"_id": "opensearch",
|
||||||
"_score": 12.0,
|
"_score": 12.0,
|
||||||
@@ -614,11 +623,11 @@ async def test_from_opensearch_respects_underscored_non_meta_fields():
|
|||||||
assert c._tagline == "You know, for search"
|
assert c._tagline == "You know, for search"
|
||||||
|
|
||||||
|
|
||||||
async def test_nested_and_object_inner_doc():
|
async def test_nested_and_object_inner_doc() -> None:
|
||||||
class MySubDocWithNested(MyDoc):
|
class MySubDocWithNested(MyDoc):
|
||||||
nested_inner = field.Nested(MyInner)
|
nested_inner = field.Nested(MyInner)
|
||||||
|
|
||||||
props = MySubDocWithNested._doc_type.mapping.to_dict()["properties"]
|
props: Any = MySubDocWithNested._doc_type.mapping.to_dict()["properties"]
|
||||||
assert props == {
|
assert props == {
|
||||||
"created_at": {"type": "date"},
|
"created_at": {"type": "date"},
|
||||||
"inner": {"properties": {"old_field": {"type": "text"}}, "type": "object"},
|
"inner": {"properties": {"old_field": {"type": "text"}}, "type": "object"},
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
# GitHub history for details.
|
# GitHub history for details.
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from _pytest.mark.structures import MarkDecorator
|
from _pytest.mark.structures import MarkDecorator
|
||||||
@@ -55,7 +56,7 @@ async def test_query_is_created_properly() -> None:
|
|||||||
} == s.to_dict()
|
} == s.to_dict()
|
||||||
|
|
||||||
|
|
||||||
async def test_query_is_created_properly_with_sort_tuple():
|
async def test_query_is_created_properly_with_sort_tuple() -> None:
|
||||||
bs = BlogSearch("python search", sort=("category", "-title"))
|
bs = BlogSearch("python search", sort=("category", "-title"))
|
||||||
s = bs.build_search()
|
s = bs.build_search()
|
||||||
|
|
||||||
@@ -79,7 +80,7 @@ async def test_query_is_created_properly_with_sort_tuple():
|
|||||||
} == s.to_dict()
|
} == s.to_dict()
|
||||||
|
|
||||||
|
|
||||||
async def test_filter_is_applied_to_search_but_not_relevant_facet():
|
async def test_filter_is_applied_to_search_but_not_relevant_facet() -> None:
|
||||||
bs = BlogSearch("python search", filters={"category": "opensearch"})
|
bs = BlogSearch("python search", filters={"category": "opensearch"})
|
||||||
s = bs.build_search()
|
s = bs.build_search()
|
||||||
|
|
||||||
@@ -102,7 +103,7 @@ async def test_filter_is_applied_to_search_but_not_relevant_facet():
|
|||||||
} == s.to_dict()
|
} == s.to_dict()
|
||||||
|
|
||||||
|
|
||||||
async def test_filters_are_applied_to_search_ant_relevant_facets():
|
async def test_filters_are_applied_to_search_ant_relevant_facets() -> None:
|
||||||
bs = BlogSearch(
|
bs = BlogSearch(
|
||||||
"python search",
|
"python search",
|
||||||
filters={"category": "opensearch", "tags": ["python", "django"]},
|
filters={"category": "opensearch", "tags": ["python", "django"]},
|
||||||
@@ -142,7 +143,7 @@ async def test_date_histogram_facet_with_1970_01_01_date() -> None:
|
|||||||
assert dhf.get_value({"key": 0}) == datetime(1970, 1, 1, 0, 0)
|
assert dhf.get_value({"key": 0}) == datetime(1970, 1, 1, 0, 0)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize( # type: ignore
|
||||||
["interval_type", "interval"],
|
["interval_type", "interval"],
|
||||||
[
|
[
|
||||||
("interval", "year"),
|
("interval", "year"),
|
||||||
@@ -169,7 +170,7 @@ async def test_date_histogram_facet_with_1970_01_01_date() -> None:
|
|||||||
("fixed_interval", "1h"),
|
("fixed_interval", "1h"),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_date_histogram_interval_types(interval_type, interval) -> None:
|
async def test_date_histogram_interval_types(interval_type: Any, interval: Any) -> None:
|
||||||
dhf = DateHistogramFacet(field="@timestamp", **{interval_type: interval})
|
dhf = DateHistogramFacet(field="@timestamp", **{interval_type: interval})
|
||||||
assert dhf.get_aggregation().to_dict() == {
|
assert dhf.get_aggregation().to_dict() == {
|
||||||
"date_histogram": {
|
"date_histogram": {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
import string
|
import string
|
||||||
from random import choice
|
from random import choice
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from _pytest.mark.structures import MarkDecorator
|
from _pytest.mark.structures import MarkDecorator
|
||||||
@@ -118,7 +119,7 @@ async def test_registered_doc_type_included_in_search() -> None:
|
|||||||
|
|
||||||
async def test_aliases_add_to_object() -> None:
|
async def test_aliases_add_to_object() -> None:
|
||||||
random_alias = "".join((choice(string.ascii_letters) for _ in range(100)))
|
random_alias = "".join((choice(string.ascii_letters) for _ in range(100)))
|
||||||
alias_dict = {random_alias: {}}
|
alias_dict: Any = {random_alias: {}}
|
||||||
|
|
||||||
index = AsyncIndex("i", using="alias")
|
index = AsyncIndex("i", using="alias")
|
||||||
index.aliases(**alias_dict)
|
index.aliases(**alias_dict)
|
||||||
@@ -128,7 +129,7 @@ async def test_aliases_add_to_object() -> None:
|
|||||||
|
|
||||||
async def test_aliases_returned_from_to_dict() -> None:
|
async def test_aliases_returned_from_to_dict() -> None:
|
||||||
random_alias = "".join((choice(string.ascii_letters) for _ in range(100)))
|
random_alias = "".join((choice(string.ascii_letters) for _ in range(100)))
|
||||||
alias_dict = {random_alias: {}}
|
alias_dict: Any = {random_alias: {}}
|
||||||
|
|
||||||
index = AsyncIndex("i", using="alias")
|
index = AsyncIndex("i", using="alias")
|
||||||
index.aliases(**alias_dict)
|
index.aliases(**alias_dict)
|
||||||
@@ -136,7 +137,7 @@ async def test_aliases_returned_from_to_dict() -> None:
|
|||||||
assert index._aliases == index.to_dict()["aliases"] == alias_dict
|
assert index._aliases == index.to_dict()["aliases"] == alias_dict
|
||||||
|
|
||||||
|
|
||||||
async def test_analyzers_added_to_object():
|
async def test_analyzers_added_to_object() -> None:
|
||||||
random_analyzer_name = "".join((choice(string.ascii_letters) for _ in range(100)))
|
random_analyzer_name = "".join((choice(string.ascii_letters) for _ in range(100)))
|
||||||
random_analyzer = analyzer(
|
random_analyzer = analyzer(
|
||||||
random_analyzer_name, tokenizer="standard", filter="standard"
|
random_analyzer_name, tokenizer="standard", filter="standard"
|
||||||
@@ -152,7 +153,7 @@ async def test_analyzers_added_to_object():
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async def test_analyzers_returned_from_to_dict():
|
async def test_analyzers_returned_from_to_dict() -> None:
|
||||||
random_analyzer_name = "".join((choice(string.ascii_letters) for _ in range(100)))
|
random_analyzer_name = "".join((choice(string.ascii_letters) for _ in range(100)))
|
||||||
random_analyzer = analyzer(
|
random_analyzer = analyzer(
|
||||||
random_analyzer_name, tokenizer="standard", filter="standard"
|
random_analyzer_name, tokenizer="standard", filter="standard"
|
||||||
@@ -173,7 +174,7 @@ async def test_conflicting_analyzer_raises_error() -> None:
|
|||||||
i.analyzer("my_analyzer", tokenizer="keyword", filter=["lowercase", "stop"])
|
i.analyzer("my_analyzer", tokenizer="keyword", filter=["lowercase", "stop"])
|
||||||
|
|
||||||
|
|
||||||
async def test_index_template_can_have_order():
|
async def test_index_template_can_have_order() -> None:
|
||||||
i = AsyncIndex("i-*")
|
i = AsyncIndex("i-*")
|
||||||
it = i.as_template("i", order=2)
|
it = i.as_template("i", order=2)
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ async def test_mapping_can_has_fields() -> None:
|
|||||||
} == m.to_dict()
|
} == m.to_dict()
|
||||||
|
|
||||||
|
|
||||||
async def test_mapping_update_is_recursive():
|
async def test_mapping_update_is_recursive() -> None:
|
||||||
m1 = mapping.AsyncMapping()
|
m1 = mapping.AsyncMapping()
|
||||||
m1.field("title", "text")
|
m1.field("title", "text")
|
||||||
m1.field("author", "object")
|
m1.field("author", "object")
|
||||||
@@ -67,7 +67,7 @@ async def test_properties_can_iterate_over_all_the_fields() -> None:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async def test_mapping_can_collect_all_analyzers_and_normalizers():
|
async def test_mapping_can_collect_all_analyzers_and_normalizers() -> None:
|
||||||
a1 = analysis.analyzer(
|
a1 = analysis.analyzer(
|
||||||
"my_analyzer1",
|
"my_analyzer1",
|
||||||
tokenizer="keyword",
|
tokenizer="keyword",
|
||||||
@@ -140,7 +140,7 @@ async def test_mapping_can_collect_all_analyzers_and_normalizers():
|
|||||||
assert json.loads(json.dumps(m.to_dict())) == m.to_dict()
|
assert json.loads(json.dumps(m.to_dict())) == m.to_dict()
|
||||||
|
|
||||||
|
|
||||||
async def test_mapping_can_collect_multiple_analyzers():
|
async def test_mapping_can_collect_multiple_analyzers() -> None:
|
||||||
a1 = analysis.analyzer(
|
a1 = analysis.analyzer(
|
||||||
"my_analyzer1",
|
"my_analyzer1",
|
||||||
tokenizer="keyword",
|
tokenizer="keyword",
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
# GitHub history for details.
|
# GitHub history for details.
|
||||||
|
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from _pytest.mark.structures import MarkDecorator
|
from _pytest.mark.structures import MarkDecorator
|
||||||
@@ -71,7 +72,7 @@ async def test_query_can_be_assigned_to() -> None:
|
|||||||
assert s.query._proxied is q
|
assert s.query._proxied is q
|
||||||
|
|
||||||
|
|
||||||
async def test_query_can_be_wrapped():
|
async def test_query_can_be_wrapped() -> None:
|
||||||
s = search.AsyncSearch().query("match", title="python")
|
s = search.AsyncSearch().query("match", title="python")
|
||||||
|
|
||||||
s.query = Q("function_score", query=s.query, field_value_factor={"field": "rating"})
|
s.query = Q("function_score", query=s.query, field_value_factor={"field": "rating"})
|
||||||
@@ -142,7 +143,7 @@ async def test_aggs_allow_two_metric() -> None:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async def test_aggs_get_copied_on_change():
|
async def test_aggs_get_copied_on_change() -> None:
|
||||||
s = search.AsyncSearch().query("match_all")
|
s = search.AsyncSearch().query("match_all")
|
||||||
s.aggs.bucket("per_tag", "terms", field="f").metric(
|
s.aggs.bucket("per_tag", "terms", field="f").metric(
|
||||||
"max_score", "max", field="score"
|
"max_score", "max", field="score"
|
||||||
@@ -155,7 +156,7 @@ async def test_aggs_get_copied_on_change():
|
|||||||
s4 = s3._clone()
|
s4 = s3._clone()
|
||||||
s4.aggs.metric("max_score", "max", field="score")
|
s4.aggs.metric("max_score", "max", field="score")
|
||||||
|
|
||||||
d = {
|
d: Any = {
|
||||||
"query": {"match_all": {}},
|
"query": {"match_all": {}},
|
||||||
"aggs": {
|
"aggs": {
|
||||||
"per_tag": {
|
"per_tag": {
|
||||||
@@ -218,7 +219,7 @@ async def test_doc_type_document_class() -> None:
|
|||||||
assert s._doc_type_map == {}
|
assert s._doc_type_map == {}
|
||||||
|
|
||||||
|
|
||||||
async def test_sort():
|
async def test_sort() -> None:
|
||||||
s = search.AsyncSearch()
|
s = search.AsyncSearch()
|
||||||
s = s.sort("fielda", "-fieldb")
|
s = s.sort("fielda", "-fieldb")
|
||||||
|
|
||||||
@@ -254,7 +255,7 @@ async def test_index() -> None:
|
|||||||
assert {"from": 3, "size": 1} == s[3].to_dict()
|
assert {"from": 3, "size": 1} == s[3].to_dict()
|
||||||
|
|
||||||
|
|
||||||
async def test_search_to_dict():
|
async def test_search_to_dict() -> None:
|
||||||
s = search.AsyncSearch()
|
s = search.AsyncSearch()
|
||||||
assert {} == s.to_dict()
|
assert {} == s.to_dict()
|
||||||
|
|
||||||
@@ -283,7 +284,7 @@ async def test_search_to_dict():
|
|||||||
assert {"size": 5, "from": 42} == s.to_dict()
|
assert {"size": 5, "from": 42} == s.to_dict()
|
||||||
|
|
||||||
|
|
||||||
async def test_complex_example():
|
async def test_complex_example() -> None:
|
||||||
s = search.AsyncSearch()
|
s = search.AsyncSearch()
|
||||||
s = (
|
s = (
|
||||||
s.query("match", title="python")
|
s.query("match", title="python")
|
||||||
@@ -334,7 +335,7 @@ async def test_complex_example():
|
|||||||
} == s.to_dict()
|
} == s.to_dict()
|
||||||
|
|
||||||
|
|
||||||
async def test_reverse():
|
async def test_reverse() -> None:
|
||||||
d = {
|
d = {
|
||||||
"query": {
|
"query": {
|
||||||
"filtered": {
|
"filtered": {
|
||||||
@@ -406,7 +407,7 @@ async def test_source() -> None:
|
|||||||
).source(["f1", "f2"]).to_dict()
|
).source(["f1", "f2"]).to_dict()
|
||||||
|
|
||||||
|
|
||||||
async def test_source_on_clone():
|
async def test_source_on_clone() -> None:
|
||||||
assert {
|
assert {
|
||||||
"_source": {"includes": ["foo.bar.*"], "excludes": ["foo.one"]},
|
"_source": {"includes": ["foo.bar.*"], "excludes": ["foo.one"]},
|
||||||
"query": {"bool": {"filter": [{"term": {"title": "python"}}]}},
|
"query": {"bool": {"filter": [{"term": {"title": "python"}}]}},
|
||||||
@@ -431,7 +432,7 @@ async def test_source_on_clear() -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def test_suggest_accepts_global_text():
|
async def test_suggest_accepts_global_text() -> None:
|
||||||
s = search.AsyncSearch.from_dict(
|
s = search.AsyncSearch.from_dict(
|
||||||
{
|
{
|
||||||
"suggest": {
|
"suggest": {
|
||||||
@@ -453,7 +454,7 @@ async def test_suggest_accepts_global_text():
|
|||||||
} == s.to_dict()
|
} == s.to_dict()
|
||||||
|
|
||||||
|
|
||||||
async def test_suggest():
|
async def test_suggest() -> None:
|
||||||
s = search.AsyncSearch()
|
s = search.AsyncSearch()
|
||||||
s = s.suggest("my_suggestion", "pyhton", term={"field": "title"})
|
s = s.suggest("my_suggestion", "pyhton", term={"field": "title"})
|
||||||
|
|
||||||
@@ -475,7 +476,7 @@ async def test_exclude() -> None:
|
|||||||
} == s.to_dict()
|
} == s.to_dict()
|
||||||
|
|
||||||
|
|
||||||
async def test_update_from_dict():
|
async def test_update_from_dict() -> None:
|
||||||
s = search.AsyncSearch()
|
s = search.AsyncSearch()
|
||||||
s.update_from_dict({"indices_boost": [{"important-documents": 2}]})
|
s.update_from_dict({"indices_boost": [{"important-documents": 2}]})
|
||||||
s.update_from_dict({"_source": ["id", "name"]})
|
s.update_from_dict({"_source": ["id", "name"]})
|
||||||
@@ -486,7 +487,7 @@ async def test_update_from_dict():
|
|||||||
} == s.to_dict()
|
} == s.to_dict()
|
||||||
|
|
||||||
|
|
||||||
async def test_rescore_query_to_dict():
|
async def test_rescore_query_to_dict() -> None:
|
||||||
s = search.AsyncSearch(index="index-name")
|
s = search.AsyncSearch(index="index-name")
|
||||||
|
|
||||||
positive_query = Q(
|
positive_query = Q(
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ async def test_ubq_starts_with_no_query() -> None:
|
|||||||
assert ubq.query._proxied is None
|
assert ubq.query._proxied is None
|
||||||
|
|
||||||
|
|
||||||
async def test_ubq_to_dict():
|
async def test_ubq_to_dict() -> None:
|
||||||
ubq = update_by_query.AsyncUpdateByQuery()
|
ubq = update_by_query.AsyncUpdateByQuery()
|
||||||
assert {} == ubq.to_dict()
|
assert {} == ubq.to_dict()
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ async def test_ubq_to_dict():
|
|||||||
assert {"extra_q": {"term": {"category": "conference"}}} == ubq.to_dict()
|
assert {"extra_q": {"term": {"category": "conference"}}} == ubq.to_dict()
|
||||||
|
|
||||||
|
|
||||||
async def test_complex_example():
|
async def test_complex_example() -> None:
|
||||||
ubq = update_by_query.AsyncUpdateByQuery()
|
ubq = update_by_query.AsyncUpdateByQuery()
|
||||||
ubq = (
|
ubq = (
|
||||||
ubq.query("match", title="python")
|
ubq.query("match", title="python")
|
||||||
@@ -95,7 +95,7 @@ async def test_exclude() -> None:
|
|||||||
} == ubq.to_dict()
|
} == ubq.to_dict()
|
||||||
|
|
||||||
|
|
||||||
async def test_reverse():
|
async def test_reverse() -> None:
|
||||||
d = {
|
d = {
|
||||||
"query": {
|
"query": {
|
||||||
"filtered": {
|
"filtered": {
|
||||||
@@ -137,7 +137,7 @@ async def test_from_dict_doesnt_need_query() -> None:
|
|||||||
assert {"script": {"source": "test"}} == ubq.to_dict()
|
assert {"script": {"source": "test"}} == ubq.to_dict()
|
||||||
|
|
||||||
|
|
||||||
async def test_overwrite_script():
|
async def test_overwrite_script() -> None:
|
||||||
ubq = update_by_query.AsyncUpdateByQuery()
|
ubq = update_by_query.AsyncUpdateByQuery()
|
||||||
ubq = ubq.script(
|
ubq = ubq.script(
|
||||||
source="ctx._source.likes += params.f", lang="painless", params={"f": 3}
|
source="ctx._source.likes += params.f", lang="painless", params={"f": 3}
|
||||||
|
|||||||
@@ -26,12 +26,14 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import mock
|
import mock
|
||||||
import pytest
|
import pytest
|
||||||
from _pytest.mark.structures import MarkDecorator
|
from _pytest.mark.structures import MarkDecorator
|
||||||
from multidict import CIMultiDict
|
from multidict import CIMultiDict
|
||||||
|
|
||||||
from opensearchpy._async._extra_imports import aiohttp
|
from opensearchpy._async._extra_imports import aiohttp # type: ignore
|
||||||
from opensearchpy._async.compat import get_running_loop
|
from opensearchpy._async.compat import get_running_loop
|
||||||
from opensearchpy.connection.http_async import AsyncHttpConnection
|
from opensearchpy.connection.http_async import AsyncHttpConnection
|
||||||
|
|
||||||
@@ -52,15 +54,15 @@ class TestAsyncHttpConnection:
|
|||||||
assert c._http_auth.password, "password"
|
assert c._http_auth.password, "password"
|
||||||
|
|
||||||
def test_auth_as_callable(self) -> None:
|
def test_auth_as_callable(self) -> None:
|
||||||
def auth_fn():
|
def auth_fn() -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
c = AsyncHttpConnection(http_auth=auth_fn)
|
c = AsyncHttpConnection(http_auth=auth_fn)
|
||||||
assert callable(c._http_auth)
|
assert callable(c._http_auth)
|
||||||
|
|
||||||
@mock.patch("aiohttp.ClientSession.request", new_callable=mock.Mock)
|
@mock.patch("aiohttp.ClientSession.request", new_callable=mock.Mock)
|
||||||
async def test_basicauth_in_request_session(self, mock_request) -> None:
|
async def test_basicauth_in_request_session(self, mock_request: Any) -> None:
|
||||||
async def do_request(*args, **kwargs):
|
async def do_request(*args: Any, **kwargs: Any) -> Any:
|
||||||
response_mock = mock.AsyncMock()
|
response_mock = mock.AsyncMock()
|
||||||
response_mock.headers = CIMultiDict()
|
response_mock.headers = CIMultiDict()
|
||||||
response_mock.status = 200
|
response_mock.status = 200
|
||||||
@@ -90,13 +92,13 @@ class TestAsyncHttpConnection:
|
|||||||
)
|
)
|
||||||
|
|
||||||
@mock.patch("aiohttp.ClientSession.request", new_callable=mock.Mock)
|
@mock.patch("aiohttp.ClientSession.request", new_callable=mock.Mock)
|
||||||
async def test_callable_in_request_session(self, mock_request) -> None:
|
async def test_callable_in_request_session(self, mock_request: Any) -> None:
|
||||||
def auth_fn(*args, **kwargs):
|
def auth_fn(*args: Any, **kwargs: Any) -> Any:
|
||||||
return {
|
return {
|
||||||
"Test": "PASSED",
|
"Test": "PASSED",
|
||||||
}
|
}
|
||||||
|
|
||||||
async def do_request(*args, **kwargs):
|
async def do_request(*args: Any, **kwargs: Any) -> Any:
|
||||||
response_mock = mock.AsyncMock()
|
response_mock = mock.AsyncMock()
|
||||||
response_mock.headers = CIMultiDict()
|
response_mock.headers = CIMultiDict()
|
||||||
response_mock.status = 200
|
response_mock.status = 200
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ class TestPluginsClient(TestCase):
|
|||||||
async def test_plugins_client(self) -> None:
|
async def test_plugins_client(self) -> None:
|
||||||
with self.assertWarns(Warning) as w:
|
with self.assertWarns(Warning) as w:
|
||||||
client = AsyncOpenSearch()
|
client = AsyncOpenSearch()
|
||||||
client.plugins.__init__(client) # double-init
|
# testing double-init here
|
||||||
|
client.plugins.__init__(client) # type: ignore
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
str(w.warnings[0].message),
|
str(w.warnings[0].message),
|
||||||
"Cannot load `alerting` directly to AsyncOpenSearch as it already exists. Use `AsyncOpenSearch.plugin.alerting` instead.",
|
"Cannot load `alerting` directly to AsyncOpenSearch as it already exists. Use `AsyncOpenSearch.plugin.alerting` instead.",
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
|
||||||
from unittest import IsolatedAsyncioTestCase
|
from unittest import IsolatedAsyncioTestCase # type: ignore
|
||||||
|
|
||||||
from opensearchpy._async.helpers.test import get_test_client
|
from opensearchpy._async.helpers.test import get_test_client
|
||||||
from opensearchpy.connection.async_connections import add_connection
|
from opensearchpy.connection.async_connections import add_connection
|
||||||
@@ -34,7 +34,7 @@ from opensearchpy.connection.async_connections import add_connection
|
|||||||
from ...utils import wipe_cluster
|
from ...utils import wipe_cluster
|
||||||
|
|
||||||
|
|
||||||
class AsyncOpenSearchTestCase(IsolatedAsyncioTestCase):
|
class AsyncOpenSearchTestCase(IsolatedAsyncioTestCase): # type: ignore
|
||||||
async def asyncSetUp(self) -> None:
|
async def asyncSetUp(self) -> None:
|
||||||
self.client = await get_test_client(
|
self.client = await get_test_client(
|
||||||
verify_certs=False, http_auth=("admin", "admin")
|
verify_certs=False, http_auth=("admin", "admin")
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from _pytest.mark.structures import MarkDecorator
|
from _pytest.mark.structures import MarkDecorator
|
||||||
@@ -39,15 +40,15 @@ from ...utils import wipe_cluster
|
|||||||
pytestmark: MarkDecorator = pytest.mark.asyncio
|
pytestmark: MarkDecorator = pytest.mark.asyncio
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="function")
|
@pytest.fixture(scope="function") # type: ignore
|
||||||
async def async_client():
|
async def async_client() -> Any:
|
||||||
client = None
|
client = None
|
||||||
try:
|
try:
|
||||||
if not hasattr(opensearchpy, "AsyncOpenSearch"):
|
if not hasattr(opensearchpy, "AsyncOpenSearch"):
|
||||||
pytest.skip("test requires 'AsyncOpenSearch'")
|
pytest.skip("test requires 'AsyncOpenSearch'")
|
||||||
|
|
||||||
kw = {"timeout": 3}
|
kw = {"timeout": 3}
|
||||||
client = opensearchpy.AsyncOpenSearch(OPENSEARCH_URL, **kw)
|
client = opensearchpy.AsyncOpenSearch(OPENSEARCH_URL, **kw) # type: ignore
|
||||||
|
|
||||||
# wait for yellow status
|
# wait for yellow status
|
||||||
for _ in range(100):
|
for _ in range(100):
|
||||||
|
|||||||
@@ -28,6 +28,8 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from _pytest.mark.structures import MarkDecorator
|
from _pytest.mark.structures import MarkDecorator
|
||||||
|
|
||||||
@@ -35,19 +37,19 @@ pytestmark: MarkDecorator = pytest.mark.asyncio
|
|||||||
|
|
||||||
|
|
||||||
class TestUnicode:
|
class TestUnicode:
|
||||||
async def test_indices_analyze(self, async_client) -> None:
|
async def test_indices_analyze(self, async_client: Any) -> None:
|
||||||
await async_client.indices.analyze(body='{"text": "привет"}')
|
await async_client.indices.analyze(body='{"text": "привет"}')
|
||||||
|
|
||||||
|
|
||||||
class TestBulk:
|
class TestBulk:
|
||||||
async def test_bulk_works_with_string_body(self, async_client) -> None:
|
async def test_bulk_works_with_string_body(self, async_client: Any) -> None:
|
||||||
docs = '{ "index" : { "_index" : "bulk_test_index", "_id" : "1" } }\n{"answer": 42}'
|
docs = '{ "index" : { "_index" : "bulk_test_index", "_id" : "1" } }\n{"answer": 42}'
|
||||||
response = await async_client.bulk(body=docs)
|
response = await async_client.bulk(body=docs)
|
||||||
|
|
||||||
assert response["errors"] is False
|
assert response["errors"] is False
|
||||||
assert len(response["items"]) == 1
|
assert len(response["items"]) == 1
|
||||||
|
|
||||||
async def test_bulk_works_with_bytestring_body(self, async_client) -> None:
|
async def test_bulk_works_with_bytestring_body(self, async_client: Any) -> None:
|
||||||
docs = b'{ "index" : { "_index" : "bulk_test_index", "_id" : "2" } }\n{"answer": 42}'
|
docs = b'{ "index" : { "_index" : "bulk_test_index", "_id" : "2" } }\n{"answer": 42}'
|
||||||
response = await async_client.bulk(body=docs)
|
response = await async_client.bulk(body=docs)
|
||||||
|
|
||||||
@@ -57,7 +59,7 @@ class TestBulk:
|
|||||||
|
|
||||||
class TestYarlMissing:
|
class TestYarlMissing:
|
||||||
async def test_aiohttp_connection_works_without_yarl(
|
async def test_aiohttp_connection_works_without_yarl(
|
||||||
self, async_client, monkeypatch
|
self, async_client: Any, monkeypatch: Any
|
||||||
) -> None:
|
) -> None:
|
||||||
# This is a defensive test case for if aiohttp suddenly stops using yarl.
|
# This is a defensive test case for if aiohttp suddenly stops using yarl.
|
||||||
from opensearchpy._async import http_aiohttp
|
from opensearchpy._async import http_aiohttp
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
import re
|
import re
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from pytest import fixture
|
from pytest import fixture
|
||||||
@@ -34,32 +35,32 @@ from test_opensearchpy.test_async.test_server.test_helpers.test_document import
|
|||||||
pytestmark = pytest.mark.asyncio
|
pytestmark = pytest.mark.asyncio
|
||||||
|
|
||||||
|
|
||||||
@fixture(scope="function")
|
@fixture(scope="function") # type: ignore
|
||||||
async def client():
|
async def client() -> Any:
|
||||||
client = await get_test_client(verify_certs=False, http_auth=("admin", "admin"))
|
client = await get_test_client(verify_certs=False, http_auth=("admin", "admin"))
|
||||||
await add_connection("default", client)
|
await add_connection("default", client)
|
||||||
return client
|
return client
|
||||||
|
|
||||||
|
|
||||||
@fixture(scope="function")
|
@fixture(scope="function") # type: ignore
|
||||||
async def opensearch_version(client):
|
async def opensearch_version(client: Any) -> Any:
|
||||||
info = await client.info()
|
info = await client.info()
|
||||||
print(info)
|
print(info)
|
||||||
yield tuple(
|
yield tuple(
|
||||||
int(x)
|
int(x)
|
||||||
for x in re.match(r"^([0-9.]+)", info["version"]["number"]).group(1).split(".")
|
for x in re.match(r"^([0-9.]+)", info["version"]["number"]).group(1).split(".") # type: ignore
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@fixture
|
@fixture # type: ignore
|
||||||
async def write_client(client):
|
async def write_client(client: Any) -> Any:
|
||||||
yield client
|
yield client
|
||||||
await client.indices.delete("test-*", ignore=404)
|
await client.indices.delete("test-*", ignore=404)
|
||||||
await client.indices.delete_template("test-template", ignore=404)
|
await client.indices.delete_template("test-template", ignore=404)
|
||||||
|
|
||||||
|
|
||||||
@fixture
|
@fixture # type: ignore
|
||||||
async def data_client(client):
|
async def data_client(client: Any) -> Any:
|
||||||
# create mappings
|
# create mappings
|
||||||
await create_git_index(client, "git")
|
await create_git_index(client, "git")
|
||||||
await create_flat_git_index(client, "flat-git")
|
await create_flat_git_index(client, "flat-git")
|
||||||
@@ -71,8 +72,8 @@ async def data_client(client):
|
|||||||
await client.indices.delete("flat-git", ignore=404)
|
await client.indices.delete("flat-git", ignore=404)
|
||||||
|
|
||||||
|
|
||||||
@fixture
|
@fixture # type: ignore
|
||||||
async def pull_request(write_client):
|
async def pull_request(write_client: Any) -> Any:
|
||||||
await PullRequest.init()
|
await PullRequest.init()
|
||||||
pr = PullRequest(
|
pr = PullRequest(
|
||||||
_id=42,
|
_id=42,
|
||||||
@@ -95,8 +96,8 @@ async def pull_request(write_client):
|
|||||||
return pr
|
return pr
|
||||||
|
|
||||||
|
|
||||||
@fixture
|
@fixture # type: ignore
|
||||||
async def setup_ubq_tests(client) -> str:
|
async def setup_ubq_tests(client: Any) -> str:
|
||||||
index = "test-git"
|
index = "test-git"
|
||||||
await create_git_index(client, index)
|
await create_git_index(client, index)
|
||||||
await async_bulk(client, TEST_GIT_DATA, raise_on_error=True, refresh=True)
|
await async_bulk(client, TEST_GIT_DATA, raise_on_error=True, refresh=True)
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
from typing import Tuple
|
from typing import Any, List
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from mock import MagicMock, patch
|
from mock import MagicMock, patch
|
||||||
@@ -40,19 +40,19 @@ pytestmark = pytest.mark.asyncio
|
|||||||
|
|
||||||
|
|
||||||
class AsyncMock(MagicMock):
|
class AsyncMock(MagicMock):
|
||||||
async def __call__(self, *args, **kwargs):
|
async def __call__(self, *args: Any, **kwargs: Any) -> Any:
|
||||||
return super(AsyncMock, self).__call__(*args, **kwargs)
|
return super(AsyncMock, self).__call__(*args, **kwargs)
|
||||||
|
|
||||||
def __await__(self):
|
def __await__(self) -> Any:
|
||||||
return self().__await__()
|
return self().__await__()
|
||||||
|
|
||||||
|
|
||||||
class FailingBulkClient(object):
|
class FailingBulkClient(object):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
client,
|
client: Any,
|
||||||
fail_at: Tuple[int] = (2,),
|
fail_at: Any = (2,),
|
||||||
fail_with=TransportError(599, "Error!", {}),
|
fail_with: TransportError = TransportError(599, "Error!", {}),
|
||||||
) -> None:
|
) -> None:
|
||||||
self.client = client
|
self.client = client
|
||||||
self._called = 0
|
self._called = 0
|
||||||
@@ -60,7 +60,7 @@ class FailingBulkClient(object):
|
|||||||
self.transport = client.transport
|
self.transport = client.transport
|
||||||
self._fail_with = fail_with
|
self._fail_with = fail_with
|
||||||
|
|
||||||
async def bulk(self, *args, **kwargs):
|
async def bulk(self, *args: Any, **kwargs: Any) -> Any:
|
||||||
self._called += 1
|
self._called += 1
|
||||||
if self._called in self._fail_at:
|
if self._called in self._fail_at:
|
||||||
raise self._fail_with
|
raise self._fail_with
|
||||||
@@ -68,7 +68,7 @@ class FailingBulkClient(object):
|
|||||||
|
|
||||||
|
|
||||||
class TestStreamingBulk(object):
|
class TestStreamingBulk(object):
|
||||||
async def test_actions_remain_unchanged(self, async_client) -> None:
|
async def test_actions_remain_unchanged(self, async_client: Any) -> None:
|
||||||
actions1 = [{"_id": 1}, {"_id": 2}]
|
actions1 = [{"_id": 1}, {"_id": 2}]
|
||||||
async for ok, item in actions.async_streaming_bulk(
|
async for ok, item in actions.async_streaming_bulk(
|
||||||
async_client, actions1, index="test-index"
|
async_client, actions1, index="test-index"
|
||||||
@@ -76,7 +76,7 @@ class TestStreamingBulk(object):
|
|||||||
assert ok
|
assert ok
|
||||||
assert [{"_id": 1}, {"_id": 2}] == actions1
|
assert [{"_id": 1}, {"_id": 2}] == actions1
|
||||||
|
|
||||||
async def test_all_documents_get_inserted(self, async_client) -> None:
|
async def test_all_documents_get_inserted(self, async_client: Any) -> None:
|
||||||
docs = [{"answer": x, "_id": x} for x in range(100)]
|
docs = [{"answer": x, "_id": x} for x in range(100)]
|
||||||
async for ok, item in actions.async_streaming_bulk(
|
async for ok, item in actions.async_streaming_bulk(
|
||||||
async_client, docs, index="test-index", refresh=True
|
async_client, docs, index="test-index", refresh=True
|
||||||
@@ -88,13 +88,13 @@ class TestStreamingBulk(object):
|
|||||||
"_source"
|
"_source"
|
||||||
]
|
]
|
||||||
|
|
||||||
async def test_documents_data_types(self, async_client):
|
async def test_documents_data_types(self, async_client: Any) -> None:
|
||||||
async def async_gen():
|
async def async_gen() -> Any:
|
||||||
for x in range(100):
|
for x in range(100):
|
||||||
await asyncio.sleep(0)
|
await asyncio.sleep(0)
|
||||||
yield {"answer": x, "_id": x}
|
yield {"answer": x, "_id": x}
|
||||||
|
|
||||||
def sync_gen():
|
def sync_gen() -> Any:
|
||||||
for x in range(100):
|
for x in range(100):
|
||||||
yield {"answer": x, "_id": x}
|
yield {"answer": x, "_id": x}
|
||||||
|
|
||||||
@@ -123,7 +123,7 @@ class TestStreamingBulk(object):
|
|||||||
]
|
]
|
||||||
|
|
||||||
async def test_all_errors_from_chunk_are_raised_on_failure(
|
async def test_all_errors_from_chunk_are_raised_on_failure(
|
||||||
self, async_client
|
self, async_client: Any
|
||||||
) -> None:
|
) -> None:
|
||||||
await async_client.indices.create(
|
await async_client.indices.create(
|
||||||
"i",
|
"i",
|
||||||
@@ -144,7 +144,7 @@ class TestStreamingBulk(object):
|
|||||||
else:
|
else:
|
||||||
assert False, "exception should have been raised"
|
assert False, "exception should have been raised"
|
||||||
|
|
||||||
async def test_different_op_types(self, async_client):
|
async def test_different_op_types(self, async_client: Any) -> None:
|
||||||
await async_client.index(index="i", id=45, body={})
|
await async_client.index(index="i", id=45, body={})
|
||||||
await async_client.index(index="i", id=42, body={})
|
await async_client.index(index="i", id=42, body={})
|
||||||
docs = [
|
docs = [
|
||||||
@@ -159,7 +159,7 @@ class TestStreamingBulk(object):
|
|||||||
assert {"answer": 42} == (await async_client.get(index="i", id=42))["_source"]
|
assert {"answer": 42} == (await async_client.get(index="i", id=42))["_source"]
|
||||||
assert {"f": "v"} == (await async_client.get(index="i", id=47))["_source"]
|
assert {"f": "v"} == (await async_client.get(index="i", id=47))["_source"]
|
||||||
|
|
||||||
async def test_transport_error_can_becaught(self, async_client):
|
async def test_transport_error_can_becaught(self, async_client: Any) -> None:
|
||||||
failing_client = FailingBulkClient(async_client)
|
failing_client = FailingBulkClient(async_client)
|
||||||
docs = [
|
docs = [
|
||||||
{"_index": "i", "_id": 47, "f": "v"},
|
{"_index": "i", "_id": 47, "f": "v"},
|
||||||
@@ -193,7 +193,7 @@ class TestStreamingBulk(object):
|
|||||||
}
|
}
|
||||||
} == results[1][1]
|
} == results[1][1]
|
||||||
|
|
||||||
async def test_rejected_documents_are_retried(self, async_client) -> None:
|
async def test_rejected_documents_are_retried(self, async_client: Any) -> None:
|
||||||
failing_client = FailingBulkClient(
|
failing_client = FailingBulkClient(
|
||||||
async_client, fail_with=TransportError(429, "Rejected!", {})
|
async_client, fail_with=TransportError(429, "Rejected!", {})
|
||||||
)
|
)
|
||||||
@@ -222,7 +222,7 @@ class TestStreamingBulk(object):
|
|||||||
assert 4 == failing_client._called
|
assert 4 == failing_client._called
|
||||||
|
|
||||||
async def test_rejected_documents_are_retried_at_most_max_retries_times(
|
async def test_rejected_documents_are_retried_at_most_max_retries_times(
|
||||||
self, async_client
|
self, async_client: Any
|
||||||
) -> None:
|
) -> None:
|
||||||
failing_client = FailingBulkClient(
|
failing_client = FailingBulkClient(
|
||||||
async_client, fail_at=(1, 2), fail_with=TransportError(429, "Rejected!", {})
|
async_client, fail_at=(1, 2), fail_with=TransportError(429, "Rejected!", {})
|
||||||
@@ -253,7 +253,7 @@ class TestStreamingBulk(object):
|
|||||||
assert 4 == failing_client._called
|
assert 4 == failing_client._called
|
||||||
|
|
||||||
async def test_transport_error_is_raised_with_max_retries(
|
async def test_transport_error_is_raised_with_max_retries(
|
||||||
self, async_client
|
self, async_client: Any
|
||||||
) -> None:
|
) -> None:
|
||||||
failing_client = FailingBulkClient(
|
failing_client = FailingBulkClient(
|
||||||
async_client,
|
async_client,
|
||||||
@@ -261,7 +261,7 @@ class TestStreamingBulk(object):
|
|||||||
fail_with=TransportError(429, "Rejected!", {}),
|
fail_with=TransportError(429, "Rejected!", {}),
|
||||||
)
|
)
|
||||||
|
|
||||||
async def streaming_bulk():
|
async def streaming_bulk() -> Any:
|
||||||
results = [
|
results = [
|
||||||
x
|
x
|
||||||
async for x in actions.async_streaming_bulk(
|
async for x in actions.async_streaming_bulk(
|
||||||
@@ -280,7 +280,7 @@ class TestStreamingBulk(object):
|
|||||||
|
|
||||||
|
|
||||||
class TestBulk(object):
|
class TestBulk(object):
|
||||||
async def test_bulk_works_with_single_item(self, async_client) -> None:
|
async def test_bulk_works_with_single_item(self, async_client: Any) -> None:
|
||||||
docs = [{"answer": 42, "_id": 1}]
|
docs = [{"answer": 42, "_id": 1}]
|
||||||
success, failed = await actions.async_bulk(
|
success, failed = await actions.async_bulk(
|
||||||
async_client, docs, index="test-index", refresh=True
|
async_client, docs, index="test-index", refresh=True
|
||||||
@@ -293,7 +293,7 @@ class TestBulk(object):
|
|||||||
"_source"
|
"_source"
|
||||||
]
|
]
|
||||||
|
|
||||||
async def test_all_documents_get_inserted(self, async_client) -> None:
|
async def test_all_documents_get_inserted(self, async_client: Any) -> None:
|
||||||
docs = [{"answer": x, "_id": x} for x in range(100)]
|
docs = [{"answer": x, "_id": x} for x in range(100)]
|
||||||
success, failed = await actions.async_bulk(
|
success, failed = await actions.async_bulk(
|
||||||
async_client, docs, index="test-index", refresh=True
|
async_client, docs, index="test-index", refresh=True
|
||||||
@@ -306,7 +306,7 @@ class TestBulk(object):
|
|||||||
"_source"
|
"_source"
|
||||||
]
|
]
|
||||||
|
|
||||||
async def test_stats_only_reports_numbers(self, async_client) -> None:
|
async def test_stats_only_reports_numbers(self, async_client: Any) -> None:
|
||||||
docs = [{"answer": x} for x in range(100)]
|
docs = [{"answer": x} for x in range(100)]
|
||||||
success, failed = await actions.async_bulk(
|
success, failed = await actions.async_bulk(
|
||||||
async_client, docs, index="test-index", refresh=True, stats_only=True
|
async_client, docs, index="test-index", refresh=True, stats_only=True
|
||||||
@@ -316,7 +316,7 @@ class TestBulk(object):
|
|||||||
assert 0 == failed
|
assert 0 == failed
|
||||||
assert 100 == (await async_client.count(index="test-index"))["count"]
|
assert 100 == (await async_client.count(index="test-index"))["count"]
|
||||||
|
|
||||||
async def test_errors_are_reported_correctly(self, async_client):
|
async def test_errors_are_reported_correctly(self, async_client: Any) -> None:
|
||||||
await async_client.indices.create(
|
await async_client.indices.create(
|
||||||
"i",
|
"i",
|
||||||
{
|
{
|
||||||
@@ -333,6 +333,7 @@ class TestBulk(object):
|
|||||||
raise_on_error=False,
|
raise_on_error=False,
|
||||||
)
|
)
|
||||||
assert 1 == success
|
assert 1 == success
|
||||||
|
assert isinstance(failed, List)
|
||||||
assert 1 == len(failed)
|
assert 1 == len(failed)
|
||||||
error = failed[0]
|
error = failed[0]
|
||||||
assert "42" == error["index"]["_id"]
|
assert "42" == error["index"]["_id"]
|
||||||
@@ -342,7 +343,7 @@ class TestBulk(object):
|
|||||||
error["index"]["error"]
|
error["index"]["error"]
|
||||||
) or "mapper_parsing_exception" in repr(error["index"]["error"])
|
) or "mapper_parsing_exception" in repr(error["index"]["error"])
|
||||||
|
|
||||||
async def test_error_is_raised(self, async_client):
|
async def test_error_is_raised(self, async_client: Any) -> None:
|
||||||
await async_client.indices.create(
|
await async_client.indices.create(
|
||||||
"i",
|
"i",
|
||||||
{
|
{
|
||||||
@@ -355,7 +356,7 @@ class TestBulk(object):
|
|||||||
with pytest.raises(BulkIndexError):
|
with pytest.raises(BulkIndexError):
|
||||||
await actions.async_bulk(async_client, [{"a": 42}, {"a": "c"}], index="i")
|
await actions.async_bulk(async_client, [{"a": 42}, {"a": "c"}], index="i")
|
||||||
|
|
||||||
async def test_ignore_error_if_raised(self, async_client):
|
async def test_ignore_error_if_raised(self, async_client: Any) -> None:
|
||||||
# ignore the status code 400 in tuple
|
# ignore the status code 400 in tuple
|
||||||
await actions.async_bulk(
|
await actions.async_bulk(
|
||||||
async_client, [{"a": 42}, {"a": "c"}], index="i", ignore_status=(400,)
|
async_client, [{"a": 42}, {"a": "c"}], index="i", ignore_status=(400,)
|
||||||
@@ -388,7 +389,7 @@ class TestBulk(object):
|
|||||||
failing_client, [{"a": 42}], index="i", ignore_status=(599,)
|
failing_client, [{"a": 42}], index="i", ignore_status=(599,)
|
||||||
)
|
)
|
||||||
|
|
||||||
async def test_errors_are_collected_properly(self, async_client):
|
async def test_errors_are_collected_properly(self, async_client: Any) -> None:
|
||||||
await async_client.indices.create(
|
await async_client.indices.create(
|
||||||
"i",
|
"i",
|
||||||
{
|
{
|
||||||
@@ -410,10 +411,12 @@ class TestBulk(object):
|
|||||||
|
|
||||||
|
|
||||||
class MockScroll:
|
class MockScroll:
|
||||||
|
calls: Any
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self.calls = []
|
self.calls = []
|
||||||
|
|
||||||
async def __call__(self, *args, **kwargs):
|
async def __call__(self, *args: Any, **kwargs: Any) -> Any:
|
||||||
self.calls.append((args, kwargs))
|
self.calls.append((args, kwargs))
|
||||||
if len(self.calls) == 1:
|
if len(self.calls) == 1:
|
||||||
return {
|
return {
|
||||||
@@ -432,25 +435,27 @@ class MockScroll:
|
|||||||
|
|
||||||
|
|
||||||
class MockResponse:
|
class MockResponse:
|
||||||
def __init__(self, resp) -> None:
|
def __init__(self, resp: Any) -> None:
|
||||||
self.resp = resp
|
self.resp = resp
|
||||||
|
|
||||||
async def __call__(self, *args, **kwargs):
|
async def __call__(self, *args: Any, **kwargs: Any) -> Any:
|
||||||
return self.resp
|
return self.resp
|
||||||
|
|
||||||
def __await__(self):
|
def __await__(self) -> Any:
|
||||||
return self().__await__()
|
return self().__await__()
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="function")
|
@pytest.fixture(scope="function") # type: ignore
|
||||||
async def scan_teardown(async_client):
|
async def scan_teardown(async_client: Any) -> Any:
|
||||||
yield
|
yield
|
||||||
await async_client.clear_scroll(scroll_id="_all")
|
await async_client.clear_scroll(scroll_id="_all")
|
||||||
|
|
||||||
|
|
||||||
class TestScan(object):
|
class TestScan(object):
|
||||||
async def test_order_can_be_preserved(self, async_client, scan_teardown):
|
async def test_order_can_be_preserved(
|
||||||
bulk = []
|
self, async_client: Any, scan_teardown: Any
|
||||||
|
) -> None:
|
||||||
|
bulk: Any = []
|
||||||
for x in range(100):
|
for x in range(100):
|
||||||
bulk.append({"index": {"_index": "test_index", "_id": x}})
|
bulk.append({"index": {"_index": "test_index", "_id": x}})
|
||||||
bulk.append({"answer": x, "correct": x == 42})
|
bulk.append({"answer": x, "correct": x == 42})
|
||||||
@@ -470,8 +475,10 @@ class TestScan(object):
|
|||||||
assert list(map(str, range(100))) == list(d["_id"] for d in docs)
|
assert list(map(str, range(100))) == list(d["_id"] for d in docs)
|
||||||
assert list(range(100)) == list(d["_source"]["answer"] for d in docs)
|
assert list(range(100)) == list(d["_source"]["answer"] for d in docs)
|
||||||
|
|
||||||
async def test_all_documents_are_read(self, async_client, scan_teardown):
|
async def test_all_documents_are_read(
|
||||||
bulk = []
|
self, async_client: Any, scan_teardown: Any
|
||||||
|
) -> None:
|
||||||
|
bulk: Any = []
|
||||||
for x in range(100):
|
for x in range(100):
|
||||||
bulk.append({"index": {"_index": "test_index", "_id": x}})
|
bulk.append({"index": {"_index": "test_index", "_id": x}})
|
||||||
bulk.append({"answer": x, "correct": x == 42})
|
bulk.append({"answer": x, "correct": x == 42})
|
||||||
@@ -486,8 +493,8 @@ class TestScan(object):
|
|||||||
assert set(map(str, range(100))) == set(d["_id"] for d in docs)
|
assert set(map(str, range(100))) == set(d["_id"] for d in docs)
|
||||||
assert set(range(100)) == set(d["_source"]["answer"] for d in docs)
|
assert set(range(100)) == set(d["_source"]["answer"] for d in docs)
|
||||||
|
|
||||||
async def test_scroll_error(self, async_client, scan_teardown):
|
async def test_scroll_error(self, async_client: Any, scan_teardown: Any) -> None:
|
||||||
bulk = []
|
bulk: Any = []
|
||||||
for x in range(4):
|
for x in range(4):
|
||||||
bulk.append({"index": {"_index": "test_index"}})
|
bulk.append({"index": {"_index": "test_index"}})
|
||||||
bulk.append({"value": x})
|
bulk.append({"value": x})
|
||||||
@@ -522,7 +529,9 @@ class TestScan(object):
|
|||||||
assert len(data) == 3
|
assert len(data) == 3
|
||||||
assert data[-1] == {"scroll_data": 42}
|
assert data[-1] == {"scroll_data": 42}
|
||||||
|
|
||||||
async def test_initial_search_error(self, async_client, scan_teardown):
|
async def test_initial_search_error(
|
||||||
|
self, async_client: Any, scan_teardown: Any
|
||||||
|
) -> None:
|
||||||
with patch.object(async_client, "clear_scroll", new_callable=AsyncMock):
|
with patch.object(async_client, "clear_scroll", new_callable=AsyncMock):
|
||||||
with patch.object(
|
with patch.object(
|
||||||
async_client,
|
async_client,
|
||||||
@@ -572,7 +581,9 @@ class TestScan(object):
|
|||||||
assert data == [{"search_data": 1}]
|
assert data == [{"search_data": 1}]
|
||||||
assert mock_scroll.calls == []
|
assert mock_scroll.calls == []
|
||||||
|
|
||||||
async def test_no_scroll_id_fast_route(self, async_client, scan_teardown) -> None:
|
async def test_no_scroll_id_fast_route(
|
||||||
|
self, async_client: Any, scan_teardown: Any
|
||||||
|
) -> None:
|
||||||
with patch.object(async_client, "search", MockResponse({"no": "_scroll_id"})):
|
with patch.object(async_client, "search", MockResponse({"no": "_scroll_id"})):
|
||||||
with patch.object(async_client, "scroll") as scroll_mock:
|
with patch.object(async_client, "scroll") as scroll_mock:
|
||||||
with patch.object(async_client, "clear_scroll") as clear_mock:
|
with patch.object(async_client, "clear_scroll") as clear_mock:
|
||||||
@@ -588,8 +599,10 @@ class TestScan(object):
|
|||||||
clear_mock.assert_not_called()
|
clear_mock.assert_not_called()
|
||||||
|
|
||||||
@patch("opensearchpy._async.helpers.actions.logger")
|
@patch("opensearchpy._async.helpers.actions.logger")
|
||||||
async def test_logger(self, logger_mock, async_client, scan_teardown):
|
async def test_logger(
|
||||||
bulk = []
|
self, logger_mock: Any, async_client: Any, scan_teardown: Any
|
||||||
|
) -> None:
|
||||||
|
bulk: Any = []
|
||||||
for x in range(4):
|
for x in range(4):
|
||||||
bulk.append({"index": {"_index": "test_index"}})
|
bulk.append({"index": {"_index": "test_index"}})
|
||||||
bulk.append({"value": x})
|
bulk.append({"value": x})
|
||||||
@@ -629,8 +642,8 @@ class TestScan(object):
|
|||||||
5,
|
5,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def test_clear_scroll(self, async_client, scan_teardown):
|
async def test_clear_scroll(self, async_client: Any, scan_teardown: Any) -> None:
|
||||||
bulk = []
|
bulk: Any = []
|
||||||
for x in range(4):
|
for x in range(4):
|
||||||
bulk.append({"index": {"_index": "test_index"}})
|
bulk.append({"index": {"_index": "test_index"}})
|
||||||
bulk.append({"value": x})
|
bulk.append({"value": x})
|
||||||
@@ -665,7 +678,7 @@ class TestScan(object):
|
|||||||
]
|
]
|
||||||
spy.assert_not_called()
|
spy.assert_not_called()
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize( # type: ignore
|
||||||
"kwargs",
|
"kwargs",
|
||||||
[
|
[
|
||||||
{"api_key": ("name", "value")},
|
{"api_key": ("name", "value")},
|
||||||
@@ -674,8 +687,8 @@ class TestScan(object):
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_scan_auth_kwargs_forwarded(
|
async def test_scan_auth_kwargs_forwarded(
|
||||||
self, async_client, scan_teardown, kwargs
|
self, async_client: Any, scan_teardown: Any, kwargs: Any
|
||||||
):
|
) -> None:
|
||||||
((key, val),) = kwargs.items()
|
((key, val),) = kwargs.items()
|
||||||
|
|
||||||
with patch.object(
|
with patch.object(
|
||||||
@@ -716,8 +729,8 @@ class TestScan(object):
|
|||||||
assert api_mock.call_args[1][key] == val
|
assert api_mock.call_args[1][key] == val
|
||||||
|
|
||||||
async def test_scan_auth_kwargs_favor_scroll_kwargs_option(
|
async def test_scan_auth_kwargs_favor_scroll_kwargs_option(
|
||||||
self, async_client, scan_teardown
|
self, async_client: Any, scan_teardown: Any
|
||||||
):
|
) -> None:
|
||||||
with patch.object(
|
with patch.object(
|
||||||
async_client,
|
async_client,
|
||||||
"search",
|
"search",
|
||||||
@@ -765,9 +778,9 @@ class TestScan(object):
|
|||||||
assert async_client.scroll.call_args[1]["sort"] == "asc"
|
assert async_client.scroll.call_args[1]["sort"] == "asc"
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="function")
|
@pytest.fixture(scope="function") # type: ignore
|
||||||
async def reindex_setup(async_client):
|
async def reindex_setup(async_client: Any) -> Any:
|
||||||
bulk = []
|
bulk: Any = []
|
||||||
for x in range(100):
|
for x in range(100):
|
||||||
bulk.append({"index": {"_index": "test_index", "_id": x}})
|
bulk.append({"index": {"_index": "test_index", "_id": x}})
|
||||||
bulk.append(
|
bulk.append(
|
||||||
@@ -783,7 +796,7 @@ async def reindex_setup(async_client):
|
|||||||
|
|
||||||
class TestReindex(object):
|
class TestReindex(object):
|
||||||
async def test_reindex_passes_kwargs_to_scan_and_bulk(
|
async def test_reindex_passes_kwargs_to_scan_and_bulk(
|
||||||
self, async_client, reindex_setup
|
self, async_client: Any, reindex_setup: Any
|
||||||
) -> None:
|
) -> None:
|
||||||
await actions.async_reindex(
|
await actions.async_reindex(
|
||||||
async_client,
|
async_client,
|
||||||
@@ -803,7 +816,9 @@ class TestReindex(object):
|
|||||||
await async_client.get(index="prod_index", id=42)
|
await async_client.get(index="prod_index", id=42)
|
||||||
)["_source"]
|
)["_source"]
|
||||||
|
|
||||||
async def test_reindex_accepts_a_query(self, async_client, reindex_setup) -> None:
|
async def test_reindex_accepts_a_query(
|
||||||
|
self, async_client: Any, reindex_setup: Any
|
||||||
|
) -> None:
|
||||||
await actions.async_reindex(
|
await actions.async_reindex(
|
||||||
async_client,
|
async_client,
|
||||||
"test_index",
|
"test_index",
|
||||||
@@ -822,7 +837,9 @@ class TestReindex(object):
|
|||||||
await async_client.get(index="prod_index", id=42)
|
await async_client.get(index="prod_index", id=42)
|
||||||
)["_source"]
|
)["_source"]
|
||||||
|
|
||||||
async def test_all_documents_get_moved(self, async_client, reindex_setup) -> None:
|
async def test_all_documents_get_moved(
|
||||||
|
self, async_client: Any, reindex_setup: Any
|
||||||
|
) -> None:
|
||||||
await actions.async_reindex(async_client, "test_index", "prod_index")
|
await actions.async_reindex(async_client, "test_index", "prod_index")
|
||||||
await async_client.indices.refresh()
|
await async_client.indices.refresh()
|
||||||
|
|
||||||
@@ -843,8 +860,8 @@ class TestReindex(object):
|
|||||||
)["_source"]
|
)["_source"]
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="function")
|
@pytest.fixture(scope="function") # type: ignore
|
||||||
async def parent_reindex_setup(async_client):
|
async def parent_reindex_setup(async_client: Any) -> None:
|
||||||
body = {
|
body = {
|
||||||
"settings": {"number_of_shards": 1, "number_of_replicas": 0},
|
"settings": {"number_of_shards": 1, "number_of_replicas": 0},
|
||||||
"mappings": {
|
"mappings": {
|
||||||
@@ -873,8 +890,8 @@ async def parent_reindex_setup(async_client):
|
|||||||
|
|
||||||
class TestParentChildReindex:
|
class TestParentChildReindex:
|
||||||
async def test_children_are_reindexed_correctly(
|
async def test_children_are_reindexed_correctly(
|
||||||
self, async_client, parent_reindex_setup
|
self, async_client: Any, parent_reindex_setup: Any
|
||||||
):
|
) -> None:
|
||||||
await actions.async_reindex(async_client, "test-index", "real-index")
|
await actions.async_reindex(async_client, "test-index", "real-index")
|
||||||
assert {"question_answer": "question"} == (
|
assert {"question_answer": "question"} == (
|
||||||
await async_client.get(index="real-index", id=42)
|
await async_client.get(index="real-index", id=42)
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ from __future__ import unicode_literals
|
|||||||
from typing import Any, Dict
|
from typing import Any, Dict
|
||||||
|
|
||||||
|
|
||||||
async def create_flat_git_index(client, index):
|
async def create_flat_git_index(client: Any, index: Any) -> None:
|
||||||
# we will use user on several places
|
# we will use user on several places
|
||||||
user_mapping = {
|
user_mapping = {
|
||||||
"properties": {"name": {"type": "text", "fields": {"raw": {"type": "keyword"}}}}
|
"properties": {"name": {"type": "text", "fields": {"raw": {"type": "keyword"}}}}
|
||||||
@@ -56,7 +56,7 @@ async def create_flat_git_index(client, index):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def create_git_index(client, index):
|
async def create_git_index(client: Any, index: Any) -> None:
|
||||||
# we will use user on several places
|
# we will use user on several places
|
||||||
user_mapping = {
|
user_mapping = {
|
||||||
"properties": {"name": {"type": "text", "fields": {"raw": {"type": "keyword"}}}}
|
"properties": {"name": {"type": "text", "fields": {"raw": {"type": "keyword"}}}}
|
||||||
@@ -1078,7 +1078,7 @@ DATA = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def flatten_doc(d) -> Dict[str, Any]:
|
def flatten_doc(d: Any) -> Dict[str, Any]:
|
||||||
src = d["_source"].copy()
|
src = d["_source"].copy()
|
||||||
del src["commit_repo"]
|
del src["commit_repo"]
|
||||||
return {"_index": "flat-git", "_id": d["_id"], "_source": src}
|
return {"_index": "flat-git", "_id": d["_id"], "_source": src}
|
||||||
@@ -1087,7 +1087,7 @@ def flatten_doc(d) -> Dict[str, Any]:
|
|||||||
FLAT_DATA = [flatten_doc(d) for d in DATA if "routing" in d]
|
FLAT_DATA = [flatten_doc(d) for d in DATA if "routing" in d]
|
||||||
|
|
||||||
|
|
||||||
def create_test_git_data(d) -> Dict[str, Any]:
|
def create_test_git_data(d: Any) -> Dict[str, Any]:
|
||||||
src = d["_source"].copy()
|
src = d["_source"].copy()
|
||||||
return {
|
return {
|
||||||
"_index": "test-git",
|
"_index": "test-git",
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from ipaddress import ip_address
|
from ipaddress import ip_address
|
||||||
|
from typing import Any, Optional
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from pytest import raises
|
from pytest import raises
|
||||||
@@ -63,7 +64,7 @@ class Repository(AsyncDocument):
|
|||||||
tags = Keyword()
|
tags = Keyword()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def search(cls):
|
def search(cls, using: Any = None, index: Optional[str] = None) -> Any:
|
||||||
return super(Repository, cls).search().filter("term", commit_repo="repo")
|
return super(Repository, cls).search().filter("term", commit_repo="repo")
|
||||||
|
|
||||||
class Index:
|
class Index:
|
||||||
@@ -116,7 +117,7 @@ class SerializationDoc(AsyncDocument):
|
|||||||
name = "test-serialization"
|
name = "test-serialization"
|
||||||
|
|
||||||
|
|
||||||
async def test_serialization(write_client):
|
async def test_serialization(write_client: Any) -> None:
|
||||||
await SerializationDoc.init()
|
await SerializationDoc.init()
|
||||||
await write_client.index(
|
await write_client.index(
|
||||||
index="test-serialization",
|
index="test-serialization",
|
||||||
@@ -129,7 +130,7 @@ async def test_serialization(write_client):
|
|||||||
"ip": ["::1", "127.0.0.1", None],
|
"ip": ["::1", "127.0.0.1", None],
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
sd = await SerializationDoc.get(id=42)
|
sd: Any = await SerializationDoc.get(id=42)
|
||||||
|
|
||||||
assert sd.i == [1, 2, 3, None]
|
assert sd.i == [1, 2, 3, None]
|
||||||
assert sd.b == [True, False, True, False, None]
|
assert sd.b == [True, False, True, False, None]
|
||||||
@@ -146,7 +147,7 @@ async def test_serialization(write_client):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async def test_nested_inner_hits_are_wrapped_properly(pull_request) -> None:
|
async def test_nested_inner_hits_are_wrapped_properly(pull_request: Any) -> None:
|
||||||
history_query = Q(
|
history_query = Q(
|
||||||
"nested",
|
"nested",
|
||||||
path="comments.history",
|
path="comments.history",
|
||||||
@@ -174,7 +175,7 @@ async def test_nested_inner_hits_are_wrapped_properly(pull_request) -> None:
|
|||||||
assert "score" in history.meta
|
assert "score" in history.meta
|
||||||
|
|
||||||
|
|
||||||
async def test_nested_inner_hits_are_deserialized_properly(pull_request) -> None:
|
async def test_nested_inner_hits_are_deserialized_properly(pull_request: Any) -> None:
|
||||||
s = PullRequest.search().query(
|
s = PullRequest.search().query(
|
||||||
"nested",
|
"nested",
|
||||||
inner_hits={},
|
inner_hits={},
|
||||||
@@ -189,7 +190,7 @@ async def test_nested_inner_hits_are_deserialized_properly(pull_request) -> None
|
|||||||
assert isinstance(pr.comments[0].created_at, datetime)
|
assert isinstance(pr.comments[0].created_at, datetime)
|
||||||
|
|
||||||
|
|
||||||
async def test_nested_top_hits_are_wrapped_properly(pull_request) -> None:
|
async def test_nested_top_hits_are_wrapped_properly(pull_request: Any) -> None:
|
||||||
s = PullRequest.search()
|
s = PullRequest.search()
|
||||||
s.aggs.bucket("comments", "nested", path="comments").metric(
|
s.aggs.bucket("comments", "nested", path="comments").metric(
|
||||||
"hits", "top_hits", size=1
|
"hits", "top_hits", size=1
|
||||||
@@ -201,7 +202,7 @@ async def test_nested_top_hits_are_wrapped_properly(pull_request) -> None:
|
|||||||
assert isinstance(r.aggregations.comments.hits.hits[0], Comment)
|
assert isinstance(r.aggregations.comments.hits.hits[0], Comment)
|
||||||
|
|
||||||
|
|
||||||
async def test_update_object_field(write_client) -> None:
|
async def test_update_object_field(write_client: Any) -> None:
|
||||||
await Wiki.init()
|
await Wiki.init()
|
||||||
w = Wiki(
|
w = Wiki(
|
||||||
owner=User(name="Honza Kral"),
|
owner=User(name="Honza Kral"),
|
||||||
@@ -221,7 +222,7 @@ async def test_update_object_field(write_client) -> None:
|
|||||||
assert w.ranked == {"test1": 0.1, "topic2": 0.2}
|
assert w.ranked == {"test1": 0.1, "topic2": 0.2}
|
||||||
|
|
||||||
|
|
||||||
async def test_update_script(write_client) -> None:
|
async def test_update_script(write_client: Any) -> None:
|
||||||
await Wiki.init()
|
await Wiki.init()
|
||||||
w = Wiki(owner=User(name="Honza Kral"), _id="opensearch-py", views=42)
|
w = Wiki(owner=User(name="Honza Kral"), _id="opensearch-py", views=42)
|
||||||
await w.save()
|
await w.save()
|
||||||
@@ -231,7 +232,7 @@ async def test_update_script(write_client) -> None:
|
|||||||
assert w.views == 47
|
assert w.views == 47
|
||||||
|
|
||||||
|
|
||||||
async def test_update_retry_on_conflict(write_client) -> None:
|
async def test_update_retry_on_conflict(write_client: Any) -> None:
|
||||||
await Wiki.init()
|
await Wiki.init()
|
||||||
w = Wiki(owner=User(name="Honza Kral"), _id="opensearch-py", views=42)
|
w = Wiki(owner=User(name="Honza Kral"), _id="opensearch-py", views=42)
|
||||||
await w.save()
|
await w.save()
|
||||||
@@ -249,8 +250,10 @@ async def test_update_retry_on_conflict(write_client) -> None:
|
|||||||
assert w.views == 52
|
assert w.views == 52
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("retry_on_conflict", [None, 0])
|
@pytest.mark.parametrize("retry_on_conflict", [None, 0]) # type: ignore
|
||||||
async def test_update_conflicting_version(write_client, retry_on_conflict) -> None:
|
async def test_update_conflicting_version(
|
||||||
|
write_client: Any, retry_on_conflict: bool
|
||||||
|
) -> None:
|
||||||
await Wiki.init()
|
await Wiki.init()
|
||||||
w = Wiki(owner=User(name="Honza Kral"), _id="opensearch-py", views=42)
|
w = Wiki(owner=User(name="Honza Kral"), _id="opensearch-py", views=42)
|
||||||
await w.save()
|
await w.save()
|
||||||
@@ -267,7 +270,7 @@ async def test_update_conflicting_version(write_client, retry_on_conflict) -> No
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def test_save_and_update_return_doc_meta(write_client) -> None:
|
async def test_save_and_update_return_doc_meta(write_client: Any) -> None:
|
||||||
await Wiki.init()
|
await Wiki.init()
|
||||||
w = Wiki(owner=User(name="Honza Kral"), _id="opensearch-py", views=42)
|
w = Wiki(owner=User(name="Honza Kral"), _id="opensearch-py", views=42)
|
||||||
resp = await w.save(return_doc_meta=True)
|
resp = await w.save(return_doc_meta=True)
|
||||||
@@ -291,33 +294,33 @@ async def test_save_and_update_return_doc_meta(write_client) -> None:
|
|||||||
assert resp.keys().__contains__("_version")
|
assert resp.keys().__contains__("_version")
|
||||||
|
|
||||||
|
|
||||||
async def test_init(write_client) -> None:
|
async def test_init(write_client: Any) -> None:
|
||||||
await Repository.init(index="test-git")
|
await Repository.init(index="test-git")
|
||||||
|
|
||||||
assert await write_client.indices.exists(index="test-git")
|
assert await write_client.indices.exists(index="test-git")
|
||||||
|
|
||||||
|
|
||||||
async def test_get_raises_404_on_index_missing(data_client) -> None:
|
async def test_get_raises_404_on_index_missing(data_client: Any) -> None:
|
||||||
with raises(NotFoundError):
|
with raises(NotFoundError):
|
||||||
await Repository.get("opensearch-dsl-php", index="not-there")
|
await Repository.get("opensearch-dsl-php", index="not-there")
|
||||||
|
|
||||||
|
|
||||||
async def test_get_raises_404_on_non_existent_id(data_client) -> None:
|
async def test_get_raises_404_on_non_existent_id(data_client: Any) -> None:
|
||||||
with raises(NotFoundError):
|
with raises(NotFoundError):
|
||||||
await Repository.get("opensearch-dsl-php")
|
await Repository.get("opensearch-dsl-php")
|
||||||
|
|
||||||
|
|
||||||
async def test_get_returns_none_if_404_ignored(data_client) -> None:
|
async def test_get_returns_none_if_404_ignored(data_client: Any) -> None:
|
||||||
assert None is await Repository.get("opensearch-dsl-php", ignore=404)
|
assert None is await Repository.get("opensearch-dsl-php", ignore=404)
|
||||||
|
|
||||||
|
|
||||||
async def test_get_returns_none_if_404_ignored_and_index_doesnt_exist(
|
async def test_get_returns_none_if_404_ignored_and_index_doesnt_exist(
|
||||||
data_client,
|
data_client: Any,
|
||||||
) -> None:
|
) -> None:
|
||||||
assert None is await Repository.get("42", index="not-there", ignore=404)
|
assert None is await Repository.get("42", index="not-there", ignore=404)
|
||||||
|
|
||||||
|
|
||||||
async def test_get(data_client) -> None:
|
async def test_get(data_client: Any) -> None:
|
||||||
opensearch_repo = await Repository.get("opensearch-py")
|
opensearch_repo = await Repository.get("opensearch-py")
|
||||||
|
|
||||||
assert isinstance(opensearch_repo, Repository)
|
assert isinstance(opensearch_repo, Repository)
|
||||||
@@ -325,15 +328,15 @@ async def test_get(data_client) -> None:
|
|||||||
assert datetime(2014, 3, 3) == opensearch_repo.created_at
|
assert datetime(2014, 3, 3) == opensearch_repo.created_at
|
||||||
|
|
||||||
|
|
||||||
async def test_exists_return_true(data_client) -> None:
|
async def test_exists_return_true(data_client: Any) -> None:
|
||||||
assert await Repository.exists("opensearch-py")
|
assert await Repository.exists("opensearch-py")
|
||||||
|
|
||||||
|
|
||||||
async def test_exists_false(data_client) -> None:
|
async def test_exists_false(data_client: Any) -> None:
|
||||||
assert not await Repository.exists("opensearch-dsl-php")
|
assert not await Repository.exists("opensearch-dsl-php")
|
||||||
|
|
||||||
|
|
||||||
async def test_get_with_tz_date(data_client) -> None:
|
async def test_get_with_tz_date(data_client: Any) -> None:
|
||||||
first_commit = await Commit.get(
|
first_commit = await Commit.get(
|
||||||
id="3ca6e1e73a071a705b4babd2f581c91a2a3e5037", routing="opensearch-py"
|
id="3ca6e1e73a071a705b4babd2f581c91a2a3e5037", routing="opensearch-py"
|
||||||
)
|
)
|
||||||
@@ -345,7 +348,7 @@ async def test_get_with_tz_date(data_client) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def test_save_with_tz_date(data_client) -> None:
|
async def test_save_with_tz_date(data_client: Any) -> None:
|
||||||
tzinfo = timezone("Europe/Prague")
|
tzinfo = timezone("Europe/Prague")
|
||||||
first_commit = await Commit.get(
|
first_commit = await Commit.get(
|
||||||
id="3ca6e1e73a071a705b4babd2f581c91a2a3e5037", routing="opensearch-py"
|
id="3ca6e1e73a071a705b4babd2f581c91a2a3e5037", routing="opensearch-py"
|
||||||
@@ -372,7 +375,7 @@ COMMIT_DOCS_WITH_MISSING = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
async def test_mget(data_client) -> None:
|
async def test_mget(data_client: Any) -> None:
|
||||||
commits = await Commit.mget(COMMIT_DOCS_WITH_MISSING)
|
commits = await Commit.mget(COMMIT_DOCS_WITH_MISSING)
|
||||||
assert commits[0] is None
|
assert commits[0] is None
|
||||||
assert commits[1].meta.id == "3ca6e1e73a071a705b4babd2f581c91a2a3e5037"
|
assert commits[1].meta.id == "3ca6e1e73a071a705b4babd2f581c91a2a3e5037"
|
||||||
@@ -380,25 +383,27 @@ async def test_mget(data_client) -> None:
|
|||||||
assert commits[3].meta.id == "eb3e543323f189fd7b698e66295427204fff5755"
|
assert commits[3].meta.id == "eb3e543323f189fd7b698e66295427204fff5755"
|
||||||
|
|
||||||
|
|
||||||
async def test_mget_raises_exception_when_missing_param_is_invalid(data_client) -> None:
|
async def test_mget_raises_exception_when_missing_param_is_invalid(
|
||||||
|
data_client: Any,
|
||||||
|
) -> None:
|
||||||
with raises(ValueError):
|
with raises(ValueError):
|
||||||
await Commit.mget(COMMIT_DOCS_WITH_MISSING, missing="raj")
|
await Commit.mget(COMMIT_DOCS_WITH_MISSING, missing="raj")
|
||||||
|
|
||||||
|
|
||||||
async def test_mget_raises_404_when_missing_param_is_raise(data_client) -> None:
|
async def test_mget_raises_404_when_missing_param_is_raise(data_client: Any) -> None:
|
||||||
with raises(NotFoundError):
|
with raises(NotFoundError):
|
||||||
await Commit.mget(COMMIT_DOCS_WITH_MISSING, missing="raise")
|
await Commit.mget(COMMIT_DOCS_WITH_MISSING, missing="raise")
|
||||||
|
|
||||||
|
|
||||||
async def test_mget_ignores_missing_docs_when_missing_param_is_skip(
|
async def test_mget_ignores_missing_docs_when_missing_param_is_skip(
|
||||||
data_client,
|
data_client: Any,
|
||||||
) -> None:
|
) -> None:
|
||||||
commits = await Commit.mget(COMMIT_DOCS_WITH_MISSING, missing="skip")
|
commits = await Commit.mget(COMMIT_DOCS_WITH_MISSING, missing="skip")
|
||||||
assert commits[0].meta.id == "3ca6e1e73a071a705b4babd2f581c91a2a3e5037"
|
assert commits[0].meta.id == "3ca6e1e73a071a705b4babd2f581c91a2a3e5037"
|
||||||
assert commits[1].meta.id == "eb3e543323f189fd7b698e66295427204fff5755"
|
assert commits[1].meta.id == "eb3e543323f189fd7b698e66295427204fff5755"
|
||||||
|
|
||||||
|
|
||||||
async def test_update_works_from_search_response(data_client) -> None:
|
async def test_update_works_from_search_response(data_client: Any) -> None:
|
||||||
opensearch_repo = (await Repository.search().execute())[0]
|
opensearch_repo = (await Repository.search().execute())[0]
|
||||||
|
|
||||||
await opensearch_repo.update(owner={"other_name": "opensearchpy"})
|
await opensearch_repo.update(owner={"other_name": "opensearchpy"})
|
||||||
@@ -409,7 +414,7 @@ async def test_update_works_from_search_response(data_client) -> None:
|
|||||||
assert "opensearch" == new_version.owner.name
|
assert "opensearch" == new_version.owner.name
|
||||||
|
|
||||||
|
|
||||||
async def test_update(data_client) -> None:
|
async def test_update(data_client: Any) -> None:
|
||||||
opensearch_repo = await Repository.get("opensearch-py")
|
opensearch_repo = await Repository.get("opensearch-py")
|
||||||
v = opensearch_repo.meta.version
|
v = opensearch_repo.meta.version
|
||||||
|
|
||||||
@@ -433,7 +438,7 @@ async def test_update(data_client) -> None:
|
|||||||
assert "primary_term" in new_version.meta
|
assert "primary_term" in new_version.meta
|
||||||
|
|
||||||
|
|
||||||
async def test_save_updates_existing_doc(data_client) -> None:
|
async def test_save_updates_existing_doc(data_client: Any) -> None:
|
||||||
opensearch_repo = await Repository.get("opensearch-py")
|
opensearch_repo = await Repository.get("opensearch-py")
|
||||||
|
|
||||||
opensearch_repo.new_field = "testing-save"
|
opensearch_repo.new_field = "testing-save"
|
||||||
@@ -446,7 +451,9 @@ async def test_save_updates_existing_doc(data_client) -> None:
|
|||||||
assert new_repo["_seq_no"] == opensearch_repo.meta.seq_no
|
assert new_repo["_seq_no"] == opensearch_repo.meta.seq_no
|
||||||
|
|
||||||
|
|
||||||
async def test_save_automatically_uses_seq_no_and_primary_term(data_client) -> None:
|
async def test_save_automatically_uses_seq_no_and_primary_term(
|
||||||
|
data_client: Any,
|
||||||
|
) -> None:
|
||||||
opensearch_repo = await Repository.get("opensearch-py")
|
opensearch_repo = await Repository.get("opensearch-py")
|
||||||
opensearch_repo.meta.seq_no += 1
|
opensearch_repo.meta.seq_no += 1
|
||||||
|
|
||||||
@@ -454,7 +461,9 @@ async def test_save_automatically_uses_seq_no_and_primary_term(data_client) -> N
|
|||||||
await opensearch_repo.save()
|
await opensearch_repo.save()
|
||||||
|
|
||||||
|
|
||||||
async def test_delete_automatically_uses_seq_no_and_primary_term(data_client) -> None:
|
async def test_delete_automatically_uses_seq_no_and_primary_term(
|
||||||
|
data_client: Any,
|
||||||
|
) -> None:
|
||||||
opensearch_repo = await Repository.get("opensearch-py")
|
opensearch_repo = await Repository.get("opensearch-py")
|
||||||
opensearch_repo.meta.seq_no += 1
|
opensearch_repo.meta.seq_no += 1
|
||||||
|
|
||||||
@@ -462,13 +471,13 @@ async def test_delete_automatically_uses_seq_no_and_primary_term(data_client) ->
|
|||||||
await opensearch_repo.delete()
|
await opensearch_repo.delete()
|
||||||
|
|
||||||
|
|
||||||
async def assert_doc_equals(expected, actual) -> None:
|
async def assert_doc_equals(expected: Any, actual: Any) -> None:
|
||||||
async for f in aiter(expected):
|
async for f in aiter(expected):
|
||||||
assert f in actual
|
assert f in actual
|
||||||
assert actual[f] == expected[f]
|
assert actual[f] == expected[f]
|
||||||
|
|
||||||
|
|
||||||
async def test_can_save_to_different_index(write_client):
|
async def test_can_save_to_different_index(write_client: Any) -> None:
|
||||||
test_repo = Repository(description="testing", meta={"id": 42})
|
test_repo = Repository(description="testing", meta={"id": 42})
|
||||||
assert await test_repo.save(index="test-document")
|
assert await test_repo.save(index="test-document")
|
||||||
|
|
||||||
@@ -483,7 +492,9 @@ async def test_can_save_to_different_index(write_client):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def test_save_without_skip_empty_will_include_empty_fields(write_client) -> None:
|
async def test_save_without_skip_empty_will_include_empty_fields(
|
||||||
|
write_client: Any,
|
||||||
|
) -> None:
|
||||||
test_repo = Repository(field_1=[], field_2=None, field_3={}, meta={"id": 42})
|
test_repo = Repository(field_1=[], field_2=None, field_3={}, meta={"id": 42})
|
||||||
assert await test_repo.save(index="test-document", skip_empty=False)
|
assert await test_repo.save(index="test-document", skip_empty=False)
|
||||||
|
|
||||||
@@ -498,7 +509,7 @@ async def test_save_without_skip_empty_will_include_empty_fields(write_client) -
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def test_delete(write_client) -> None:
|
async def test_delete(write_client: Any) -> None:
|
||||||
await write_client.create(
|
await write_client.create(
|
||||||
index="test-document",
|
index="test-document",
|
||||||
id="opensearch-py",
|
id="opensearch-py",
|
||||||
@@ -519,11 +530,11 @@ async def test_delete(write_client) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def test_search(data_client) -> None:
|
async def test_search(data_client: Any) -> None:
|
||||||
assert await Repository.search().count() == 1
|
assert await Repository.search().count() == 1
|
||||||
|
|
||||||
|
|
||||||
async def test_search_returns_proper_doc_classes(data_client) -> None:
|
async def test_search_returns_proper_doc_classes(data_client: Any) -> None:
|
||||||
result = await Repository.search().execute()
|
result = await Repository.search().execute()
|
||||||
|
|
||||||
opensearch_repo = result.hits[0]
|
opensearch_repo = result.hits[0]
|
||||||
@@ -532,8 +543,10 @@ async def test_search_returns_proper_doc_classes(data_client) -> None:
|
|||||||
assert opensearch_repo.owner.name == "opensearch"
|
assert opensearch_repo.owner.name == "opensearch"
|
||||||
|
|
||||||
|
|
||||||
async def test_refresh_mapping(data_client) -> None:
|
async def test_refresh_mapping(data_client: Any) -> None:
|
||||||
class Commit(AsyncDocument):
|
class Commit(AsyncDocument):
|
||||||
|
_index: Any
|
||||||
|
|
||||||
class Index:
|
class Index:
|
||||||
name = "git"
|
name = "git"
|
||||||
|
|
||||||
@@ -546,7 +559,7 @@ async def test_refresh_mapping(data_client) -> None:
|
|||||||
assert isinstance(Commit._index._mapping["committed_date"], Date)
|
assert isinstance(Commit._index._mapping["committed_date"], Date)
|
||||||
|
|
||||||
|
|
||||||
async def test_highlight_in_meta(data_client) -> None:
|
async def test_highlight_in_meta(data_client: Any) -> None:
|
||||||
commit = (
|
commit = (
|
||||||
await Commit.search()
|
await Commit.search()
|
||||||
.query("match", description="inverting")
|
.query("match", description="inverting")
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
# GitHub history for details.
|
# GitHub history for details.
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from _pytest.mark.structures import MarkDecorator
|
from _pytest.mark.structures import MarkDecorator
|
||||||
@@ -54,8 +55,8 @@ class MetricSearch(AsyncFacetedSearch):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="function")
|
@pytest.fixture(scope="function") # type: ignore
|
||||||
def commit_search_cls(opensearch_version):
|
def commit_search_cls(opensearch_version: Any) -> Any:
|
||||||
interval_kwargs = {"fixed_interval": "1d"}
|
interval_kwargs = {"fixed_interval": "1d"}
|
||||||
|
|
||||||
class CommitSearch(AsyncFacetedSearch):
|
class CommitSearch(AsyncFacetedSearch):
|
||||||
@@ -79,8 +80,8 @@ def commit_search_cls(opensearch_version):
|
|||||||
return CommitSearch
|
return CommitSearch
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="function")
|
@pytest.fixture(scope="function") # type: ignore
|
||||||
def repo_search_cls(opensearch_version):
|
def repo_search_cls(opensearch_version: Any) -> Any:
|
||||||
interval_type = "calendar_interval"
|
interval_type = "calendar_interval"
|
||||||
|
|
||||||
class RepoSearch(AsyncFacetedSearch):
|
class RepoSearch(AsyncFacetedSearch):
|
||||||
@@ -93,15 +94,15 @@ def repo_search_cls(opensearch_version):
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
def search(self):
|
def search(self) -> Any:
|
||||||
s = super(RepoSearch, self).search()
|
s = super(RepoSearch, self).search()
|
||||||
return s.filter("term", commit_repo="repo")
|
return s.filter("term", commit_repo="repo")
|
||||||
|
|
||||||
return RepoSearch
|
return RepoSearch
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="function")
|
@pytest.fixture(scope="function") # type: ignore
|
||||||
def pr_search_cls(opensearch_version):
|
def pr_search_cls(opensearch_version: Any) -> Any:
|
||||||
interval_type = "calendar_interval"
|
interval_type = "calendar_interval"
|
||||||
|
|
||||||
class PRSearch(AsyncFacetedSearch):
|
class PRSearch(AsyncFacetedSearch):
|
||||||
@@ -119,7 +120,7 @@ def pr_search_cls(opensearch_version):
|
|||||||
return PRSearch
|
return PRSearch
|
||||||
|
|
||||||
|
|
||||||
async def test_facet_with_custom_metric(data_client) -> None:
|
async def test_facet_with_custom_metric(data_client: Any) -> None:
|
||||||
ms = MetricSearch()
|
ms = MetricSearch()
|
||||||
r = await ms.execute()
|
r = await ms.execute()
|
||||||
|
|
||||||
@@ -128,7 +129,7 @@ async def test_facet_with_custom_metric(data_client) -> None:
|
|||||||
assert dates[0] == 1399038439000
|
assert dates[0] == 1399038439000
|
||||||
|
|
||||||
|
|
||||||
async def test_nested_facet(pull_request, pr_search_cls) -> None:
|
async def test_nested_facet(pull_request: Any, pr_search_cls: Any) -> None:
|
||||||
prs = pr_search_cls()
|
prs = pr_search_cls()
|
||||||
r = await prs.execute()
|
r = await prs.execute()
|
||||||
|
|
||||||
@@ -136,7 +137,7 @@ async def test_nested_facet(pull_request, pr_search_cls) -> None:
|
|||||||
assert [(datetime(2018, 1, 1, 0, 0), 1, False)] == r.facets.comments
|
assert [(datetime(2018, 1, 1, 0, 0), 1, False)] == r.facets.comments
|
||||||
|
|
||||||
|
|
||||||
async def test_nested_facet_with_filter(pull_request, pr_search_cls) -> None:
|
async def test_nested_facet_with_filter(pull_request: Any, pr_search_cls: Any) -> None:
|
||||||
prs = pr_search_cls(filters={"comments": datetime(2018, 1, 1, 0, 0)})
|
prs = pr_search_cls(filters={"comments": datetime(2018, 1, 1, 0, 0)})
|
||||||
r = await prs.execute()
|
r = await prs.execute()
|
||||||
|
|
||||||
@@ -148,7 +149,7 @@ async def test_nested_facet_with_filter(pull_request, pr_search_cls) -> None:
|
|||||||
assert not r.hits
|
assert not r.hits
|
||||||
|
|
||||||
|
|
||||||
async def test_datehistogram_facet(data_client, repo_search_cls) -> None:
|
async def test_datehistogram_facet(data_client: Any, repo_search_cls: Any) -> None:
|
||||||
rs = repo_search_cls()
|
rs = repo_search_cls()
|
||||||
r = await rs.execute()
|
r = await rs.execute()
|
||||||
|
|
||||||
@@ -156,7 +157,7 @@ async def test_datehistogram_facet(data_client, repo_search_cls) -> None:
|
|||||||
assert [(datetime(2014, 3, 1, 0, 0), 1, False)] == r.facets.created
|
assert [(datetime(2014, 3, 1, 0, 0), 1, False)] == r.facets.created
|
||||||
|
|
||||||
|
|
||||||
async def test_boolean_facet(data_client, repo_search_cls) -> None:
|
async def test_boolean_facet(data_client: Any, repo_search_cls: Any) -> None:
|
||||||
rs = repo_search_cls()
|
rs = repo_search_cls()
|
||||||
r = await rs.execute()
|
r = await rs.execute()
|
||||||
|
|
||||||
@@ -167,7 +168,7 @@ async def test_boolean_facet(data_client, repo_search_cls) -> None:
|
|||||||
|
|
||||||
|
|
||||||
async def test_empty_search_finds_everything(
|
async def test_empty_search_finds_everything(
|
||||||
data_client, opensearch_version, commit_search_cls
|
data_client: Any, opensearch_version: Any, commit_search_cls: Any
|
||||||
) -> None:
|
) -> None:
|
||||||
cs = commit_search_cls()
|
cs = commit_search_cls()
|
||||||
r = await cs.execute()
|
r = await cs.execute()
|
||||||
@@ -213,7 +214,7 @@ async def test_empty_search_finds_everything(
|
|||||||
|
|
||||||
|
|
||||||
async def test_term_filters_are_shown_as_selected_and_data_is_filtered(
|
async def test_term_filters_are_shown_as_selected_and_data_is_filtered(
|
||||||
data_client, commit_search_cls
|
data_client: Any, commit_search_cls: Any
|
||||||
) -> None:
|
) -> None:
|
||||||
cs = commit_search_cls(filters={"files": "test_opensearchpy/test_dsl"})
|
cs = commit_search_cls(filters={"files": "test_opensearchpy/test_dsl"})
|
||||||
|
|
||||||
@@ -259,7 +260,7 @@ async def test_term_filters_are_shown_as_selected_and_data_is_filtered(
|
|||||||
|
|
||||||
|
|
||||||
async def test_range_filters_are_shown_as_selected_and_data_is_filtered(
|
async def test_range_filters_are_shown_as_selected_and_data_is_filtered(
|
||||||
data_client, commit_search_cls
|
data_client: Any, commit_search_cls: Any
|
||||||
) -> None:
|
) -> None:
|
||||||
cs = commit_search_cls(filters={"deletions": "better"})
|
cs = commit_search_cls(filters={"deletions": "better"})
|
||||||
|
|
||||||
@@ -268,7 +269,7 @@ async def test_range_filters_are_shown_as_selected_and_data_is_filtered(
|
|||||||
assert 19 == r.hits.total.value
|
assert 19 == r.hits.total.value
|
||||||
|
|
||||||
|
|
||||||
async def test_pagination(data_client, commit_search_cls) -> None:
|
async def test_pagination(data_client: Any, commit_search_cls: Any) -> None:
|
||||||
cs = commit_search_cls()
|
cs = commit_search_cls()
|
||||||
cs = cs[0:20]
|
cs = cs[0:20]
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
# Modifications Copyright OpenSearch Contributors. See
|
# Modifications Copyright OpenSearch Contributors. See
|
||||||
# GitHub history for details.
|
# GitHub history for details.
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from _pytest.mark.structures import MarkDecorator
|
from _pytest.mark.structures import MarkDecorator
|
||||||
|
|
||||||
@@ -24,7 +26,7 @@ class Post(AsyncDocument):
|
|||||||
published_from = Date()
|
published_from = Date()
|
||||||
|
|
||||||
|
|
||||||
async def test_index_template_works(write_client) -> None:
|
async def test_index_template_works(write_client: Any) -> None:
|
||||||
it = AsyncIndexTemplate("test-template", "test-*")
|
it = AsyncIndexTemplate("test-template", "test-*")
|
||||||
it.document(Post)
|
it.document(Post)
|
||||||
it.settings(number_of_replicas=0, number_of_shards=1)
|
it.settings(number_of_replicas=0, number_of_shards=1)
|
||||||
@@ -45,7 +47,7 @@ async def test_index_template_works(write_client) -> None:
|
|||||||
} == await write_client.indices.get_mapping(index="test-blog")
|
} == await write_client.indices.get_mapping(index="test-blog")
|
||||||
|
|
||||||
|
|
||||||
async def test_index_can_be_saved_even_with_settings(write_client) -> None:
|
async def test_index_can_be_saved_even_with_settings(write_client: Any) -> None:
|
||||||
i = AsyncIndex("test-blog", using=write_client)
|
i = AsyncIndex("test-blog", using=write_client)
|
||||||
i.settings(number_of_shards=3, number_of_replicas=0)
|
i.settings(number_of_shards=3, number_of_replicas=0)
|
||||||
await i.save()
|
await i.save()
|
||||||
@@ -60,12 +62,14 @@ async def test_index_can_be_saved_even_with_settings(write_client) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def test_index_exists(data_client) -> None:
|
async def test_index_exists(data_client: Any) -> None:
|
||||||
assert await AsyncIndex("git").exists()
|
assert await AsyncIndex("git").exists()
|
||||||
assert not await AsyncIndex("not-there").exists()
|
assert not await AsyncIndex("not-there").exists()
|
||||||
|
|
||||||
|
|
||||||
async def test_index_can_be_created_with_settings_and_mappings(write_client) -> None:
|
async def test_index_can_be_created_with_settings_and_mappings(
|
||||||
|
write_client: Any,
|
||||||
|
) -> None:
|
||||||
i = AsyncIndex("test-blog", using=write_client)
|
i = AsyncIndex("test-blog", using=write_client)
|
||||||
i.document(Post)
|
i.document(Post)
|
||||||
i.settings(number_of_replicas=0, number_of_shards=1)
|
i.settings(number_of_replicas=0, number_of_shards=1)
|
||||||
@@ -90,7 +94,7 @@ async def test_index_can_be_created_with_settings_and_mappings(write_client) ->
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async def test_delete(write_client) -> None:
|
async def test_delete(write_client: Any) -> None:
|
||||||
await write_client.indices.create(
|
await write_client.indices.create(
|
||||||
index="test-index",
|
index="test-index",
|
||||||
body={"settings": {"number_of_replicas": 0, "number_of_shards": 1}},
|
body={"settings": {"number_of_replicas": 0, "number_of_shards": 1}},
|
||||||
@@ -101,9 +105,9 @@ async def test_delete(write_client) -> None:
|
|||||||
assert not await write_client.indices.exists(index="test-index")
|
assert not await write_client.indices.exists(index="test-index")
|
||||||
|
|
||||||
|
|
||||||
async def test_multiple_indices_with_same_doc_type_work(write_client) -> None:
|
async def test_multiple_indices_with_same_doc_type_work(write_client: Any) -> None:
|
||||||
i1 = AsyncIndex("test-index-1", using=write_client)
|
i1: Any = AsyncIndex("test-index-1", using=write_client)
|
||||||
i2 = AsyncIndex("test-index-2", using=write_client)
|
i2: Any = AsyncIndex("test-index-2", using=write_client)
|
||||||
|
|
||||||
for i in i1, i2:
|
for i in i1, i2:
|
||||||
i.document(Post)
|
i.document(Post)
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
# Modifications Copyright OpenSearch Contributors. See
|
# Modifications Copyright OpenSearch Contributors. See
|
||||||
# GitHub history for details.
|
# GitHub history for details.
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from _pytest.mark.structures import MarkDecorator
|
from _pytest.mark.structures import MarkDecorator
|
||||||
from pytest import raises
|
from pytest import raises
|
||||||
@@ -19,7 +21,7 @@ from opensearchpy.helpers import analysis
|
|||||||
pytestmark: MarkDecorator = pytest.mark.asyncio
|
pytestmark: MarkDecorator = pytest.mark.asyncio
|
||||||
|
|
||||||
|
|
||||||
async def test_mapping_saved_into_opensearch(write_client) -> None:
|
async def test_mapping_saved_into_opensearch(write_client: Any) -> None:
|
||||||
m = mapping.AsyncMapping()
|
m = mapping.AsyncMapping()
|
||||||
m.field(
|
m.field(
|
||||||
"name", "text", analyzer=analysis.analyzer("my_analyzer", tokenizer="keyword")
|
"name", "text", analyzer=analysis.analyzer("my_analyzer", tokenizer="keyword")
|
||||||
@@ -40,7 +42,7 @@ async def test_mapping_saved_into_opensearch(write_client) -> None:
|
|||||||
|
|
||||||
|
|
||||||
async def test_mapping_saved_into_opensearch_when_index_already_exists_closed(
|
async def test_mapping_saved_into_opensearch_when_index_already_exists_closed(
|
||||||
write_client,
|
write_client: Any,
|
||||||
) -> None:
|
) -> None:
|
||||||
m = mapping.AsyncMapping()
|
m = mapping.AsyncMapping()
|
||||||
m.field(
|
m.field(
|
||||||
@@ -65,7 +67,7 @@ async def test_mapping_saved_into_opensearch_when_index_already_exists_closed(
|
|||||||
|
|
||||||
|
|
||||||
async def test_mapping_saved_into_opensearch_when_index_already_exists_with_analysis(
|
async def test_mapping_saved_into_opensearch_when_index_already_exists_with_analysis(
|
||||||
write_client,
|
write_client: Any,
|
||||||
) -> None:
|
) -> None:
|
||||||
m = mapping.AsyncMapping()
|
m = mapping.AsyncMapping()
|
||||||
analyzer = analysis.analyzer("my_analyzer", tokenizer="keyword")
|
analyzer = analysis.analyzer("my_analyzer", tokenizer="keyword")
|
||||||
@@ -95,7 +97,7 @@ async def test_mapping_saved_into_opensearch_when_index_already_exists_with_anal
|
|||||||
} == await write_client.indices.get_mapping(index="test-mapping")
|
} == await write_client.indices.get_mapping(index="test-mapping")
|
||||||
|
|
||||||
|
|
||||||
async def test_mapping_gets_updated_from_opensearch(write_client):
|
async def test_mapping_gets_updated_from_opensearch(write_client: Any) -> None:
|
||||||
await write_client.indices.create(
|
await write_client.indices.create(
|
||||||
index="test-mapping",
|
index="test-mapping",
|
||||||
body={
|
body={
|
||||||
|
|||||||
@@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from _pytest.mark.structures import MarkDecorator
|
from _pytest.mark.structures import MarkDecorator
|
||||||
from pytest import raises
|
from pytest import raises
|
||||||
@@ -29,7 +31,7 @@ class Repository(AsyncDocument):
|
|||||||
tags = Keyword()
|
tags = Keyword()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def search(cls):
|
def search(cls, using: Any = None, index: Any = None) -> Any:
|
||||||
return super(Repository, cls).search().filter("term", commit_repo="repo")
|
return super(Repository, cls).search().filter("term", commit_repo="repo")
|
||||||
|
|
||||||
class Index:
|
class Index:
|
||||||
@@ -41,7 +43,7 @@ class Commit(AsyncDocument):
|
|||||||
name = "flat-git"
|
name = "flat-git"
|
||||||
|
|
||||||
|
|
||||||
async def test_filters_aggregation_buckets_are_accessible(data_client) -> None:
|
async def test_filters_aggregation_buckets_are_accessible(data_client: Any) -> None:
|
||||||
has_tests_query = Q("term", files="test_opensearchpy/test_dsl")
|
has_tests_query = Q("term", files="test_opensearchpy/test_dsl")
|
||||||
s = Commit.search()[0:0]
|
s = Commit.search()[0:0]
|
||||||
s.aggs.bucket("top_authors", "terms", field="author.name.raw").bucket(
|
s.aggs.bucket("top_authors", "terms", field="author.name.raw").bucket(
|
||||||
@@ -62,7 +64,7 @@ async def test_filters_aggregation_buckets_are_accessible(data_client) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def test_top_hits_are_wrapped_in_response(data_client) -> None:
|
async def test_top_hits_are_wrapped_in_response(data_client: Any) -> None:
|
||||||
s = Commit.search()[0:0]
|
s = Commit.search()[0:0]
|
||||||
s.aggs.bucket("top_authors", "terms", field="author.name.raw").metric(
|
s.aggs.bucket("top_authors", "terms", field="author.name.raw").metric(
|
||||||
"top_commits", "top_hits", size=5
|
"top_commits", "top_hits", size=5
|
||||||
@@ -78,7 +80,7 @@ async def test_top_hits_are_wrapped_in_response(data_client) -> None:
|
|||||||
assert isinstance(hits[0], Commit)
|
assert isinstance(hits[0], Commit)
|
||||||
|
|
||||||
|
|
||||||
async def test_inner_hits_are_wrapped_in_response(data_client) -> None:
|
async def test_inner_hits_are_wrapped_in_response(data_client: Any) -> None:
|
||||||
s = AsyncSearch(index="git")[0:1].query(
|
s = AsyncSearch(index="git")[0:1].query(
|
||||||
"has_parent", parent_type="repo", inner_hits={}, query=Q("match_all")
|
"has_parent", parent_type="repo", inner_hits={}, query=Q("match_all")
|
||||||
)
|
)
|
||||||
@@ -89,7 +91,7 @@ async def test_inner_hits_are_wrapped_in_response(data_client) -> None:
|
|||||||
assert repr(commit.meta.inner_hits.repo[0]).startswith("<Hit(git/opensearch-py): ")
|
assert repr(commit.meta.inner_hits.repo[0]).startswith("<Hit(git/opensearch-py): ")
|
||||||
|
|
||||||
|
|
||||||
async def test_scan_respects_doc_types(data_client) -> None:
|
async def test_scan_respects_doc_types(data_client: Any) -> None:
|
||||||
result = Repository.search().scan()
|
result = Repository.search().scan()
|
||||||
repos = await get_result(result)
|
repos = await get_result(result)
|
||||||
|
|
||||||
@@ -98,7 +100,7 @@ async def test_scan_respects_doc_types(data_client) -> None:
|
|||||||
assert repos[0].organization == "opensearch"
|
assert repos[0].organization == "opensearch"
|
||||||
|
|
||||||
|
|
||||||
async def test_scan_iterates_through_all_docs(data_client) -> None:
|
async def test_scan_iterates_through_all_docs(data_client: Any) -> None:
|
||||||
s = AsyncSearch(index="flat-git")
|
s = AsyncSearch(index="flat-git")
|
||||||
result = s.scan()
|
result = s.scan()
|
||||||
commits = await get_result(result)
|
commits = await get_result(result)
|
||||||
@@ -107,14 +109,14 @@ async def test_scan_iterates_through_all_docs(data_client) -> None:
|
|||||||
assert {d["_id"] for d in FLAT_DATA} == {c.meta.id for c in commits}
|
assert {d["_id"] for d in FLAT_DATA} == {c.meta.id for c in commits}
|
||||||
|
|
||||||
|
|
||||||
async def get_result(b):
|
async def get_result(b: Any) -> Any:
|
||||||
a = []
|
a = []
|
||||||
async for i in b:
|
async for i in b:
|
||||||
a.append(i)
|
a.append(i)
|
||||||
return a
|
return a
|
||||||
|
|
||||||
|
|
||||||
async def test_multi_search(data_client) -> None:
|
async def test_multi_search(data_client: Any) -> None:
|
||||||
s1 = Repository.search()
|
s1 = Repository.search()
|
||||||
s2 = AsyncSearch(index="flat-git")
|
s2 = AsyncSearch(index="flat-git")
|
||||||
|
|
||||||
@@ -131,7 +133,7 @@ async def test_multi_search(data_client) -> None:
|
|||||||
assert r2._search is s2
|
assert r2._search is s2
|
||||||
|
|
||||||
|
|
||||||
async def test_multi_missing(data_client) -> None:
|
async def test_multi_missing(data_client: Any) -> None:
|
||||||
s1 = Repository.search()
|
s1 = Repository.search()
|
||||||
s2 = AsyncSearch(index="flat-git")
|
s2 = AsyncSearch(index="flat-git")
|
||||||
s3 = AsyncSearch(index="does_not_exist")
|
s3 = AsyncSearch(index="does_not_exist")
|
||||||
@@ -154,7 +156,7 @@ async def test_multi_missing(data_client) -> None:
|
|||||||
assert r3 is None
|
assert r3 is None
|
||||||
|
|
||||||
|
|
||||||
async def test_raw_subfield_can_be_used_in_aggs(data_client) -> None:
|
async def test_raw_subfield_can_be_used_in_aggs(data_client: Any) -> None:
|
||||||
s = AsyncSearch(index="git")[0:0]
|
s = AsyncSearch(index="git")[0:0]
|
||||||
s.aggs.bucket("authors", "terms", field="author.name.raw", size=1)
|
s.aggs.bucket("authors", "terms", field="author.name.raw", size=1)
|
||||||
r = await s.execute()
|
r = await s.execute()
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
# Modifications Copyright OpenSearch Contributors. See
|
# Modifications Copyright OpenSearch Contributors. See
|
||||||
# GitHub history for details.
|
# GitHub history for details.
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from _pytest.mark.structures import MarkDecorator
|
from _pytest.mark.structures import MarkDecorator
|
||||||
|
|
||||||
@@ -17,7 +19,9 @@ from opensearchpy.helpers.search import Q
|
|||||||
pytestmark: MarkDecorator = pytest.mark.asyncio
|
pytestmark: MarkDecorator = pytest.mark.asyncio
|
||||||
|
|
||||||
|
|
||||||
async def test_update_by_query_no_script(write_client, setup_ubq_tests) -> None:
|
async def test_update_by_query_no_script(
|
||||||
|
write_client: Any, setup_ubq_tests: Any
|
||||||
|
) -> None:
|
||||||
index = setup_ubq_tests
|
index = setup_ubq_tests
|
||||||
|
|
||||||
ubq = (
|
ubq = (
|
||||||
@@ -36,7 +40,9 @@ async def test_update_by_query_no_script(write_client, setup_ubq_tests) -> None:
|
|||||||
assert response.success()
|
assert response.success()
|
||||||
|
|
||||||
|
|
||||||
async def test_update_by_query_with_script(write_client, setup_ubq_tests) -> None:
|
async def test_update_by_query_with_script(
|
||||||
|
write_client: Any, setup_ubq_tests: Any
|
||||||
|
) -> None:
|
||||||
index = setup_ubq_tests
|
index = setup_ubq_tests
|
||||||
|
|
||||||
ubq = (
|
ubq = (
|
||||||
@@ -53,7 +59,9 @@ async def test_update_by_query_with_script(write_client, setup_ubq_tests) -> Non
|
|||||||
assert response.version_conflicts == 0
|
assert response.version_conflicts == 0
|
||||||
|
|
||||||
|
|
||||||
async def test_delete_by_query_with_script(write_client, setup_ubq_tests) -> None:
|
async def test_delete_by_query_with_script(
|
||||||
|
write_client: Any, setup_ubq_tests: Any
|
||||||
|
) -> None:
|
||||||
index = setup_ubq_tests
|
index = setup_ubq_tests
|
||||||
|
|
||||||
ubq = (
|
ubq = (
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class TestAlertingPlugin(AsyncOpenSearchTestCase):
|
|||||||
(OPENSEARCH_VERSION) and (OPENSEARCH_VERSION < (2, 0, 0)),
|
(OPENSEARCH_VERSION) and (OPENSEARCH_VERSION < (2, 0, 0)),
|
||||||
"Plugin not supported for opensearch version",
|
"Plugin not supported for opensearch version",
|
||||||
)
|
)
|
||||||
async def test_create_destination(self):
|
async def test_create_destination(self) -> None:
|
||||||
# Test to create alert destination
|
# Test to create alert destination
|
||||||
dummy_destination = {
|
dummy_destination = {
|
||||||
"name": "my-destination",
|
"name": "my-destination",
|
||||||
@@ -59,7 +59,7 @@ class TestAlertingPlugin(AsyncOpenSearchTestCase):
|
|||||||
(OPENSEARCH_VERSION) and (OPENSEARCH_VERSION < (2, 0, 0)),
|
(OPENSEARCH_VERSION) and (OPENSEARCH_VERSION < (2, 0, 0)),
|
||||||
"Plugin not supported for opensearch version",
|
"Plugin not supported for opensearch version",
|
||||||
)
|
)
|
||||||
async def test_create_monitor(self):
|
async def test_create_monitor(self) -> None:
|
||||||
# Create a dummy destination
|
# Create a dummy destination
|
||||||
await self.test_create_destination()
|
await self.test_create_destination()
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ clients.
|
|||||||
"""
|
"""
|
||||||
import inspect
|
import inspect
|
||||||
import warnings
|
import warnings
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from _pytest.mark.structures import MarkDecorator
|
from _pytest.mark.structures import MarkDecorator
|
||||||
@@ -53,14 +54,14 @@ pytestmark: MarkDecorator = pytest.mark.asyncio
|
|||||||
OPENSEARCH_VERSION = None
|
OPENSEARCH_VERSION = None
|
||||||
|
|
||||||
|
|
||||||
async def await_if_coro(x):
|
async def await_if_coro(x: Any) -> Any:
|
||||||
if inspect.iscoroutine(x):
|
if inspect.iscoroutine(x):
|
||||||
return await x
|
return await x
|
||||||
return x
|
return x
|
||||||
|
|
||||||
|
|
||||||
class AsyncYamlRunner(YamlRunner):
|
class AsyncYamlRunner(YamlRunner):
|
||||||
async def setup(self):
|
async def setup(self) -> None:
|
||||||
# Pull skips from individual tests to not do unnecessary setup.
|
# Pull skips from individual tests to not do unnecessary setup.
|
||||||
skip_code = []
|
skip_code = []
|
||||||
for action in self._run_code:
|
for action in self._run_code:
|
||||||
@@ -78,12 +79,12 @@ class AsyncYamlRunner(YamlRunner):
|
|||||||
if self._setup_code:
|
if self._setup_code:
|
||||||
await self.run_code(self._setup_code)
|
await self.run_code(self._setup_code)
|
||||||
|
|
||||||
async def teardown(self) -> None:
|
async def teardown(self) -> Any:
|
||||||
if self._teardown_code:
|
if self._teardown_code:
|
||||||
self.section("teardown")
|
self.section("teardown")
|
||||||
await self.run_code(self._teardown_code)
|
await self.run_code(self._teardown_code)
|
||||||
|
|
||||||
async def opensearch_version(self):
|
async def opensearch_version(self) -> Any:
|
||||||
global OPENSEARCH_VERSION
|
global OPENSEARCH_VERSION
|
||||||
if OPENSEARCH_VERSION is None:
|
if OPENSEARCH_VERSION is None:
|
||||||
version_string = (await self.client.info())["version"]["number"]
|
version_string = (await self.client.info())["version"]["number"]
|
||||||
@@ -93,10 +94,10 @@ class AsyncYamlRunner(YamlRunner):
|
|||||||
OPENSEARCH_VERSION = tuple(int(v) if v.isdigit() else 999 for v in version)
|
OPENSEARCH_VERSION = tuple(int(v) if v.isdigit() else 999 for v in version)
|
||||||
return OPENSEARCH_VERSION
|
return OPENSEARCH_VERSION
|
||||||
|
|
||||||
def section(self, name) -> None:
|
def section(self, name: str) -> None:
|
||||||
print(("=" * 10) + " " + name + " " + ("=" * 10))
|
print(("=" * 10) + " " + name + " " + ("=" * 10))
|
||||||
|
|
||||||
async def run(self) -> None:
|
async def run(self) -> Any:
|
||||||
try:
|
try:
|
||||||
await self.setup()
|
await self.setup()
|
||||||
self.section("test")
|
self.section("test")
|
||||||
@@ -107,7 +108,7 @@ class AsyncYamlRunner(YamlRunner):
|
|||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
async def run_code(self, test) -> None:
|
async def run_code(self, test: Any) -> Any:
|
||||||
"""Execute an instruction based on its type."""
|
"""Execute an instruction based on its type."""
|
||||||
for action in test:
|
for action in test:
|
||||||
assert len(action) == 1
|
assert len(action) == 1
|
||||||
@@ -119,7 +120,7 @@ class AsyncYamlRunner(YamlRunner):
|
|||||||
else:
|
else:
|
||||||
raise RuntimeError("Invalid action type %r" % (action_type,))
|
raise RuntimeError("Invalid action type %r" % (action_type,))
|
||||||
|
|
||||||
async def run_do(self, action) -> None:
|
async def run_do(self, action: Any) -> Any:
|
||||||
api = self.client
|
api = self.client
|
||||||
headers = action.pop("headers", None)
|
headers = action.pop("headers", None)
|
||||||
catch = action.pop("catch", None)
|
catch = action.pop("catch", None)
|
||||||
@@ -171,7 +172,7 @@ class AsyncYamlRunner(YamlRunner):
|
|||||||
|
|
||||||
# Filter out warnings raised by other components.
|
# Filter out warnings raised by other components.
|
||||||
caught_warnings = [
|
caught_warnings = [
|
||||||
str(w.message)
|
str(w.message) # type: ignore
|
||||||
for w in caught_warnings
|
for w in caught_warnings
|
||||||
if w.category == OpenSearchWarning
|
if w.category == OpenSearchWarning
|
||||||
and str(w.message) not in allowed_warnings
|
and str(w.message) not in allowed_warnings
|
||||||
@@ -179,13 +180,13 @@ class AsyncYamlRunner(YamlRunner):
|
|||||||
|
|
||||||
# Sorting removes the issue with order raised. We only care about
|
# Sorting removes the issue with order raised. We only care about
|
||||||
# if all warnings are raised in the single API call.
|
# if all warnings are raised in the single API call.
|
||||||
if warn and sorted(warn) != sorted(caught_warnings):
|
if warn and sorted(warn) != sorted(caught_warnings): # type: ignore
|
||||||
raise AssertionError(
|
raise AssertionError(
|
||||||
"Expected warnings not equal to actual warnings: expected=%r actual=%r"
|
"Expected warnings not equal to actual warnings: expected=%r actual=%r"
|
||||||
% (warn, caught_warnings)
|
% (warn, caught_warnings)
|
||||||
)
|
)
|
||||||
|
|
||||||
async def run_skip(self, skip) -> None:
|
async def run_skip(self, skip: Any) -> Any:
|
||||||
if "features" in skip:
|
if "features" in skip:
|
||||||
features = skip["features"]
|
features = skip["features"]
|
||||||
if not isinstance(features, (tuple, list)):
|
if not isinstance(features, (tuple, list)):
|
||||||
@@ -205,19 +206,19 @@ class AsyncYamlRunner(YamlRunner):
|
|||||||
if min_version <= (await self.opensearch_version()) <= max_version:
|
if min_version <= (await self.opensearch_version()) <= max_version:
|
||||||
pytest.skip(reason)
|
pytest.skip(reason)
|
||||||
|
|
||||||
async def _feature_enabled(self, name) -> bool:
|
async def _feature_enabled(self, name: str) -> Any:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="function")
|
@pytest.fixture(scope="function") # type: ignore
|
||||||
def async_runner(async_client):
|
def async_runner(async_client: Any) -> AsyncYamlRunner:
|
||||||
return AsyncYamlRunner(async_client)
|
return AsyncYamlRunner(async_client)
|
||||||
|
|
||||||
|
|
||||||
if RUN_ASYNC_REST_API_TESTS:
|
if RUN_ASYNC_REST_API_TESTS:
|
||||||
|
|
||||||
@pytest.mark.parametrize("test_spec", YAML_TEST_SPECS)
|
@pytest.mark.parametrize("test_spec", YAML_TEST_SPECS) # type: ignore
|
||||||
async def test_rest_api_spec(test_spec, async_runner) -> None:
|
async def test_rest_api_spec(test_spec: Any, async_runner: Any) -> None:
|
||||||
if test_spec.get("skip", False):
|
if test_spec.get("skip", False):
|
||||||
pytest.skip("Manually skipped in 'SKIP_TESTS'")
|
pytest.skip("Manually skipped in 'SKIP_TESTS'")
|
||||||
async_runner.use_spec(test_spec)
|
async_runner.use_spec(test_spec)
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from unittest import IsolatedAsyncioTestCase
|
from unittest import IsolatedAsyncioTestCase # type: ignore
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from _pytest.mark.structures import MarkDecorator
|
from _pytest.mark.structures import MarkDecorator
|
||||||
@@ -23,7 +23,7 @@ from opensearchpy.exceptions import NotFoundError
|
|||||||
pytestmark: MarkDecorator = pytest.mark.asyncio
|
pytestmark: MarkDecorator = pytest.mark.asyncio
|
||||||
|
|
||||||
|
|
||||||
class TestSecurityPlugin(IsolatedAsyncioTestCase):
|
class TestSecurityPlugin(IsolatedAsyncioTestCase): # type: ignore
|
||||||
ROLE_NAME = "test-role"
|
ROLE_NAME = "test-role"
|
||||||
ROLE_CONTENT = {
|
ROLE_CONTENT = {
|
||||||
"cluster_permissions": ["cluster_monitor"],
|
"cluster_permissions": ["cluster_monitor"],
|
||||||
@@ -123,7 +123,7 @@ class TestSecurityPlugin(IsolatedAsyncioTestCase):
|
|||||||
else:
|
else:
|
||||||
assert False
|
assert False
|
||||||
|
|
||||||
async def test_create_user_with_role(self):
|
async def test_create_user_with_role(self) -> None:
|
||||||
await self.test_create_role()
|
await self.test_create_role()
|
||||||
|
|
||||||
# Test to create user
|
# Test to create user
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ pytestmark: MarkDecorator = pytest.mark.asyncio
|
|||||||
|
|
||||||
|
|
||||||
class TestAsyncSigner:
|
class TestAsyncSigner:
|
||||||
def mock_session(self):
|
def mock_session(self) -> Mock:
|
||||||
access_key = uuid.uuid4().hex
|
access_key = uuid.uuid4().hex
|
||||||
secret_key = uuid.uuid4().hex
|
secret_key = uuid.uuid4().hex
|
||||||
token = uuid.uuid4().hex
|
token = uuid.uuid4().hex
|
||||||
@@ -37,7 +37,7 @@ class TestAsyncSigner:
|
|||||||
from opensearchpy.helpers.asyncsigner import AWSV4SignerAsyncAuth
|
from opensearchpy.helpers.asyncsigner import AWSV4SignerAsyncAuth
|
||||||
|
|
||||||
auth = AWSV4SignerAsyncAuth(self.mock_session(), region)
|
auth = AWSV4SignerAsyncAuth(self.mock_session(), region)
|
||||||
headers = auth("GET", "http://localhost", {}, {})
|
headers = auth("GET", "http://localhost")
|
||||||
assert "Authorization" in headers
|
assert "Authorization" in headers
|
||||||
assert "X-Amz-Date" in headers
|
assert "X-Amz-Date" in headers
|
||||||
assert "X-Amz-Security-Token" in headers
|
assert "X-Amz-Security-Token" in headers
|
||||||
@@ -48,7 +48,7 @@ class TestAsyncSigner:
|
|||||||
from opensearchpy.helpers.asyncsigner import AWSV4SignerAsyncAuth
|
from opensearchpy.helpers.asyncsigner import AWSV4SignerAsyncAuth
|
||||||
|
|
||||||
with pytest.raises(ValueError) as e:
|
with pytest.raises(ValueError) as e:
|
||||||
AWSV4SignerAsyncAuth(session, None)
|
AWSV4SignerAsyncAuth(session, None) # type: ignore
|
||||||
assert str(e.value) == "Region cannot be empty"
|
assert str(e.value) == "Region cannot be empty"
|
||||||
|
|
||||||
with pytest.raises(ValueError) as e:
|
with pytest.raises(ValueError) as e:
|
||||||
@@ -71,7 +71,7 @@ class TestAsyncSigner:
|
|||||||
from opensearchpy.helpers.asyncsigner import AWSV4SignerAsyncAuth
|
from opensearchpy.helpers.asyncsigner import AWSV4SignerAsyncAuth
|
||||||
|
|
||||||
auth = AWSV4SignerAsyncAuth(self.mock_session(), region, service)
|
auth = AWSV4SignerAsyncAuth(self.mock_session(), region, service)
|
||||||
headers = auth("GET", "http://localhost", {}, {})
|
headers = auth("GET", "http://localhost")
|
||||||
assert "Authorization" in headers
|
assert "Authorization" in headers
|
||||||
assert "X-Amz-Date" in headers
|
assert "X-Amz-Date" in headers
|
||||||
assert "X-Amz-Security-Token" in headers
|
assert "X-Amz-Security-Token" in headers
|
||||||
@@ -79,7 +79,7 @@ class TestAsyncSigner:
|
|||||||
|
|
||||||
|
|
||||||
class TestAsyncSignerWithFrozenCredentials(TestAsyncSigner):
|
class TestAsyncSignerWithFrozenCredentials(TestAsyncSigner):
|
||||||
def mock_session(self, disable_get_frozen: bool = True):
|
def mock_session(self, disable_get_frozen: bool = True) -> Mock:
|
||||||
access_key = uuid.uuid4().hex
|
access_key = uuid.uuid4().hex
|
||||||
secret_key = uuid.uuid4().hex
|
secret_key = uuid.uuid4().hex
|
||||||
token = uuid.uuid4().hex
|
token = uuid.uuid4().hex
|
||||||
@@ -99,7 +99,7 @@ class TestAsyncSignerWithFrozenCredentials(TestAsyncSigner):
|
|||||||
mock_session = self.mock_session()
|
mock_session = self.mock_session()
|
||||||
|
|
||||||
auth = AWSV4SignerAsyncAuth(mock_session, region)
|
auth = AWSV4SignerAsyncAuth(mock_session, region)
|
||||||
headers = auth("GET", "http://localhost", {}, {})
|
headers = auth("GET", "http://localhost")
|
||||||
assert "Authorization" in headers
|
assert "Authorization" in headers
|
||||||
assert "X-Amz-Date" in headers
|
assert "X-Amz-Date" in headers
|
||||||
assert "X-Amz-Security-Token" in headers
|
assert "X-Amz-Security-Token" in headers
|
||||||
|
|||||||
@@ -45,16 +45,16 @@ pytestmark: MarkDecorator = pytest.mark.asyncio
|
|||||||
|
|
||||||
|
|
||||||
class DummyConnection(Connection):
|
class DummyConnection(Connection):
|
||||||
def __init__(self, **kwargs) -> None:
|
def __init__(self, **kwargs: Any) -> None:
|
||||||
self.exception = kwargs.pop("exception", None)
|
self.exception = kwargs.pop("exception", None)
|
||||||
self.status, self.data = kwargs.pop("status", 200), kwargs.pop("data", "{}")
|
self.status, self.data = kwargs.pop("status", 200), kwargs.pop("data", "{}")
|
||||||
self.headers = kwargs.pop("headers", {})
|
self.headers = kwargs.pop("headers", {})
|
||||||
self.delay = kwargs.pop("delay", 0)
|
self.delay = kwargs.pop("delay", 0)
|
||||||
self.calls = []
|
self.calls: Any = []
|
||||||
self.closed = False
|
self.closed = False
|
||||||
super(DummyConnection, self).__init__(**kwargs)
|
super(DummyConnection, self).__init__(**kwargs)
|
||||||
|
|
||||||
async def perform_request(self, *args, **kwargs) -> Any:
|
async def perform_request(self, *args: Any, **kwargs: Any) -> Any:
|
||||||
if self.closed:
|
if self.closed:
|
||||||
raise RuntimeError("This connection is closed")
|
raise RuntimeError("This connection is closed")
|
||||||
if self.delay:
|
if self.delay:
|
||||||
@@ -123,15 +123,15 @@ CLUSTER_NODES_7x_PUBLISH_HOST = """{
|
|||||||
|
|
||||||
class TestTransport:
|
class TestTransport:
|
||||||
async def test_single_connection_uses_dummy_connection_pool(self) -> None:
|
async def test_single_connection_uses_dummy_connection_pool(self) -> None:
|
||||||
t = AsyncTransport([{}])
|
t1: Any = AsyncTransport([{}])
|
||||||
await t._async_call()
|
await t1._async_call()
|
||||||
assert isinstance(t.connection_pool, DummyConnectionPool)
|
assert isinstance(t1.connection_pool, DummyConnectionPool)
|
||||||
t = AsyncTransport([{"host": "localhost"}])
|
t2: Any = AsyncTransport([{"host": "localhost"}])
|
||||||
await t._async_call()
|
await t2._async_call()
|
||||||
assert isinstance(t.connection_pool, DummyConnectionPool)
|
assert isinstance(t2.connection_pool, DummyConnectionPool)
|
||||||
|
|
||||||
async def test_request_timeout_extracted_from_params_and_passed(self) -> None:
|
async def test_request_timeout_extracted_from_params_and_passed(self) -> None:
|
||||||
t = AsyncTransport([{}], connection_class=DummyConnection)
|
t: Any = AsyncTransport([{}], connection_class=DummyConnection)
|
||||||
|
|
||||||
await t.perform_request("GET", "/", params={"request_timeout": 42})
|
await t.perform_request("GET", "/", params={"request_timeout": 42})
|
||||||
assert 1 == len(t.get_connection().calls)
|
assert 1 == len(t.get_connection().calls)
|
||||||
@@ -143,7 +143,7 @@ class TestTransport:
|
|||||||
} == t.get_connection().calls[0][1]
|
} == t.get_connection().calls[0][1]
|
||||||
|
|
||||||
async def test_timeout_extracted_from_params_and_passed(self) -> None:
|
async def test_timeout_extracted_from_params_and_passed(self) -> None:
|
||||||
t = AsyncTransport([{}], connection_class=DummyConnection)
|
t: Any = AsyncTransport([{}], connection_class=DummyConnection)
|
||||||
|
|
||||||
await t.perform_request("GET", "/", params={"timeout": 84})
|
await t.perform_request("GET", "/", params={"timeout": 84})
|
||||||
assert 1 == len(t.get_connection().calls)
|
assert 1 == len(t.get_connection().calls)
|
||||||
@@ -154,8 +154,10 @@ class TestTransport:
|
|||||||
"headers": None,
|
"headers": None,
|
||||||
} == t.get_connection().calls[0][1]
|
} == t.get_connection().calls[0][1]
|
||||||
|
|
||||||
async def test_opaque_id(self):
|
async def test_opaque_id(self) -> None:
|
||||||
t = AsyncTransport([{}], opaque_id="app-1", connection_class=DummyConnection)
|
t: Any = AsyncTransport(
|
||||||
|
[{}], opaque_id="app-1", connection_class=DummyConnection
|
||||||
|
)
|
||||||
|
|
||||||
await t.perform_request("GET", "/")
|
await t.perform_request("GET", "/")
|
||||||
assert 1 == len(t.get_connection().calls)
|
assert 1 == len(t.get_connection().calls)
|
||||||
@@ -176,8 +178,8 @@ class TestTransport:
|
|||||||
"headers": {"x-opaque-id": "request-1"},
|
"headers": {"x-opaque-id": "request-1"},
|
||||||
} == t.get_connection().calls[1][1]
|
} == t.get_connection().calls[1][1]
|
||||||
|
|
||||||
async def test_request_with_custom_user_agent_header(self):
|
async def test_request_with_custom_user_agent_header(self) -> None:
|
||||||
t = AsyncTransport([{}], connection_class=DummyConnection)
|
t: Any = AsyncTransport([{}], connection_class=DummyConnection)
|
||||||
|
|
||||||
await t.perform_request(
|
await t.perform_request(
|
||||||
"GET", "/", headers={"user-agent": "my-custom-value/1.2.3"}
|
"GET", "/", headers={"user-agent": "my-custom-value/1.2.3"}
|
||||||
@@ -190,7 +192,7 @@ class TestTransport:
|
|||||||
} == t.get_connection().calls[0][1]
|
} == t.get_connection().calls[0][1]
|
||||||
|
|
||||||
async def test_send_get_body_as_source(self) -> None:
|
async def test_send_get_body_as_source(self) -> None:
|
||||||
t = AsyncTransport(
|
t: Any = AsyncTransport(
|
||||||
[{}], send_get_body_as="source", connection_class=DummyConnection
|
[{}], send_get_body_as="source", connection_class=DummyConnection
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -199,7 +201,7 @@ class TestTransport:
|
|||||||
assert ("GET", "/", {"source": "{}"}, None) == t.get_connection().calls[0][0]
|
assert ("GET", "/", {"source": "{}"}, None) == t.get_connection().calls[0][0]
|
||||||
|
|
||||||
async def test_send_get_body_as_post(self) -> None:
|
async def test_send_get_body_as_post(self) -> None:
|
||||||
t = AsyncTransport(
|
t: Any = AsyncTransport(
|
||||||
[{}], send_get_body_as="POST", connection_class=DummyConnection
|
[{}], send_get_body_as="POST", connection_class=DummyConnection
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -208,7 +210,7 @@ class TestTransport:
|
|||||||
assert ("POST", "/", None, b"{}") == t.get_connection().calls[0][0]
|
assert ("POST", "/", None, b"{}") == t.get_connection().calls[0][0]
|
||||||
|
|
||||||
async def test_body_gets_encoded_into_bytes(self) -> None:
|
async def test_body_gets_encoded_into_bytes(self) -> None:
|
||||||
t = AsyncTransport([{}], connection_class=DummyConnection)
|
t: Any = AsyncTransport([{}], connection_class=DummyConnection)
|
||||||
|
|
||||||
await t.perform_request("GET", "/", body="你好")
|
await t.perform_request("GET", "/", body="你好")
|
||||||
assert 1 == len(t.get_connection().calls)
|
assert 1 == len(t.get_connection().calls)
|
||||||
@@ -220,7 +222,7 @@ class TestTransport:
|
|||||||
) == t.get_connection().calls[0][0]
|
) == t.get_connection().calls[0][0]
|
||||||
|
|
||||||
async def test_body_bytes_get_passed_untouched(self) -> None:
|
async def test_body_bytes_get_passed_untouched(self) -> None:
|
||||||
t = AsyncTransport([{}], connection_class=DummyConnection)
|
t: Any = AsyncTransport([{}], connection_class=DummyConnection)
|
||||||
|
|
||||||
body = b"\xe4\xbd\xa0\xe5\xa5\xbd"
|
body = b"\xe4\xbd\xa0\xe5\xa5\xbd"
|
||||||
await t.perform_request("GET", "/", body=body)
|
await t.perform_request("GET", "/", body=body)
|
||||||
@@ -228,7 +230,7 @@ class TestTransport:
|
|||||||
assert ("GET", "/", None, body) == t.get_connection().calls[0][0]
|
assert ("GET", "/", None, body) == t.get_connection().calls[0][0]
|
||||||
|
|
||||||
async def test_body_surrogates_replaced_encoded_into_bytes(self) -> None:
|
async def test_body_surrogates_replaced_encoded_into_bytes(self) -> None:
|
||||||
t = AsyncTransport([{}], connection_class=DummyConnection)
|
t: Any = AsyncTransport([{}], connection_class=DummyConnection)
|
||||||
|
|
||||||
await t.perform_request("GET", "/", body="你好\uda6a")
|
await t.perform_request("GET", "/", body="你好\uda6a")
|
||||||
assert 1 == len(t.get_connection().calls)
|
assert 1 == len(t.get_connection().calls)
|
||||||
@@ -240,36 +242,36 @@ class TestTransport:
|
|||||||
) == t.get_connection().calls[0][0]
|
) == t.get_connection().calls[0][0]
|
||||||
|
|
||||||
async def test_kwargs_passed_on_to_connections(self) -> None:
|
async def test_kwargs_passed_on_to_connections(self) -> None:
|
||||||
t = AsyncTransport([{"host": "google.com"}], port=123)
|
t: Any = AsyncTransport([{"host": "google.com"}], port=123)
|
||||||
await t._async_call()
|
await t._async_call()
|
||||||
assert 1 == len(t.connection_pool.connections)
|
assert 1 == len(t.connection_pool.connections)
|
||||||
assert "http://google.com:123" == t.connection_pool.connections[0].host
|
assert "http://google.com:123" == t.connection_pool.connections[0].host
|
||||||
|
|
||||||
async def test_kwargs_passed_on_to_connection_pool(self) -> None:
|
async def test_kwargs_passed_on_to_connection_pool(self) -> None:
|
||||||
dt = object()
|
dt = object()
|
||||||
t = AsyncTransport([{}, {}], dead_timeout=dt)
|
t: Any = AsyncTransport([{}, {}], dead_timeout=dt)
|
||||||
await t._async_call()
|
await t._async_call()
|
||||||
assert dt is t.connection_pool.dead_timeout
|
assert dt is t.connection_pool.dead_timeout
|
||||||
|
|
||||||
async def test_custom_connection_class(self) -> None:
|
async def test_custom_connection_class(self) -> None:
|
||||||
class MyConnection(object):
|
class MyConnection(object):
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs: Any) -> None:
|
||||||
self.kwargs = kwargs
|
self.kwargs = kwargs
|
||||||
|
|
||||||
t = AsyncTransport([{}], connection_class=MyConnection)
|
t: Any = AsyncTransport([{}], connection_class=MyConnection)
|
||||||
await t._async_call()
|
await t._async_call()
|
||||||
assert 1 == len(t.connection_pool.connections)
|
assert 1 == len(t.connection_pool.connections)
|
||||||
assert isinstance(t.connection_pool.connections[0], MyConnection)
|
assert isinstance(t.connection_pool.connections[0], MyConnection)
|
||||||
|
|
||||||
async def test_add_connection(self) -> None:
|
async def test_add_connection(self) -> None:
|
||||||
t = AsyncTransport([{}], randomize_hosts=False)
|
t: Any = AsyncTransport([{}], randomize_hosts=False)
|
||||||
t.add_connection({"host": "google.com", "port": 1234})
|
t.add_connection({"host": "google.com", "port": 1234})
|
||||||
|
|
||||||
assert 2 == len(t.connection_pool.connections)
|
assert 2 == len(t.connection_pool.connections)
|
||||||
assert "http://google.com:1234" == t.connection_pool.connections[1].host
|
assert "http://google.com:1234" == t.connection_pool.connections[1].host
|
||||||
|
|
||||||
async def test_request_will_fail_after_X_retries(self) -> None:
|
async def test_request_will_fail_after_X_retries(self) -> None:
|
||||||
t = AsyncTransport(
|
t: Any = AsyncTransport(
|
||||||
[{"exception": ConnectionError("abandon ship")}],
|
[{"exception": ConnectionError("abandon ship")}],
|
||||||
connection_class=DummyConnection,
|
connection_class=DummyConnection,
|
||||||
)
|
)
|
||||||
@@ -284,7 +286,7 @@ class TestTransport:
|
|||||||
assert 4 == len(t.get_connection().calls)
|
assert 4 == len(t.get_connection().calls)
|
||||||
|
|
||||||
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 = AsyncTransport(
|
t: Any = AsyncTransport(
|
||||||
[{"exception": ConnectionError("abandon ship")}] * 2,
|
[{"exception": ConnectionError("abandon ship")}] * 2,
|
||||||
connection_class=DummyConnection,
|
connection_class=DummyConnection,
|
||||||
)
|
)
|
||||||
@@ -302,7 +304,7 @@ class TestTransport:
|
|||||||
self,
|
self,
|
||||||
) -> None:
|
) -> None:
|
||||||
for method in ("GET", "HEAD"):
|
for method in ("GET", "HEAD"):
|
||||||
t = AsyncTransport([{}, {}], connection_class=DummyConnection)
|
t: Any = AsyncTransport([{}, {}], connection_class=DummyConnection)
|
||||||
await t._async_call()
|
await t._async_call()
|
||||||
con1 = t.connection_pool.get_connection()
|
con1 = t.connection_pool.get_connection()
|
||||||
con2 = t.connection_pool.get_connection()
|
con2 = t.connection_pool.get_connection()
|
||||||
@@ -314,7 +316,9 @@ class TestTransport:
|
|||||||
assert 1 == len(t.connection_pool.dead_count)
|
assert 1 == len(t.connection_pool.dead_count)
|
||||||
|
|
||||||
async def test_sniff_will_use_seed_connections(self) -> None:
|
async def test_sniff_will_use_seed_connections(self) -> None:
|
||||||
t = AsyncTransport([{"data": CLUSTER_NODES}], connection_class=DummyConnection)
|
t: Any = AsyncTransport(
|
||||||
|
[{"data": CLUSTER_NODES}], connection_class=DummyConnection
|
||||||
|
)
|
||||||
await t._async_call()
|
await t._async_call()
|
||||||
t.set_connections([{"data": "invalid"}])
|
t.set_connections([{"data": "invalid"}])
|
||||||
|
|
||||||
@@ -323,7 +327,7 @@ class TestTransport:
|
|||||||
assert "http://1.1.1.1:123" == t.get_connection().host
|
assert "http://1.1.1.1:123" == t.get_connection().host
|
||||||
|
|
||||||
async def test_sniff_on_start_fetches_and_uses_nodes_list(self) -> None:
|
async def test_sniff_on_start_fetches_and_uses_nodes_list(self) -> None:
|
||||||
t = AsyncTransport(
|
t: Any = AsyncTransport(
|
||||||
[{"data": CLUSTER_NODES}],
|
[{"data": CLUSTER_NODES}],
|
||||||
connection_class=DummyConnection,
|
connection_class=DummyConnection,
|
||||||
sniff_on_start=True,
|
sniff_on_start=True,
|
||||||
@@ -335,7 +339,7 @@ class TestTransport:
|
|||||||
assert "http://1.1.1.1:123" == t.get_connection().host
|
assert "http://1.1.1.1:123" == t.get_connection().host
|
||||||
|
|
||||||
async def test_sniff_on_start_ignores_sniff_timeout(self) -> None:
|
async def test_sniff_on_start_ignores_sniff_timeout(self) -> None:
|
||||||
t = AsyncTransport(
|
t: Any = AsyncTransport(
|
||||||
[{"data": CLUSTER_NODES}],
|
[{"data": CLUSTER_NODES}],
|
||||||
connection_class=DummyConnection,
|
connection_class=DummyConnection,
|
||||||
sniff_on_start=True,
|
sniff_on_start=True,
|
||||||
@@ -349,7 +353,7 @@ class TestTransport:
|
|||||||
].calls[0]
|
].calls[0]
|
||||||
|
|
||||||
async def test_sniff_uses_sniff_timeout(self) -> None:
|
async def test_sniff_uses_sniff_timeout(self) -> None:
|
||||||
t = AsyncTransport(
|
t: Any = AsyncTransport(
|
||||||
[{"data": CLUSTER_NODES}],
|
[{"data": CLUSTER_NODES}],
|
||||||
connection_class=DummyConnection,
|
connection_class=DummyConnection,
|
||||||
sniff_timeout=42,
|
sniff_timeout=42,
|
||||||
@@ -361,8 +365,8 @@ class TestTransport:
|
|||||||
0
|
0
|
||||||
].calls[0]
|
].calls[0]
|
||||||
|
|
||||||
async def test_sniff_reuses_connection_instances_if_possible(self):
|
async def test_sniff_reuses_connection_instances_if_possible(self) -> None:
|
||||||
t = AsyncTransport(
|
t: Any = AsyncTransport(
|
||||||
[{"data": CLUSTER_NODES}, {"host": "1.1.1.1", "port": 123}],
|
[{"data": CLUSTER_NODES}, {"host": "1.1.1.1", "port": 123}],
|
||||||
connection_class=DummyConnection,
|
connection_class=DummyConnection,
|
||||||
randomize_hosts=False,
|
randomize_hosts=False,
|
||||||
@@ -375,8 +379,8 @@ class TestTransport:
|
|||||||
assert 1 == len(t.connection_pool.connections)
|
assert 1 == len(t.connection_pool.connections)
|
||||||
assert connection is t.get_connection()
|
assert connection is t.get_connection()
|
||||||
|
|
||||||
async def test_sniff_on_fail_triggers_sniffing_on_fail(self):
|
async def test_sniff_on_fail_triggers_sniffing_on_fail(self) -> None:
|
||||||
t = AsyncTransport(
|
t: Any = AsyncTransport(
|
||||||
[{"exception": ConnectionError("abandon ship")}, {"data": CLUSTER_NODES}],
|
[{"exception": ConnectionError("abandon ship")}, {"data": CLUSTER_NODES}],
|
||||||
connection_class=DummyConnection,
|
connection_class=DummyConnection,
|
||||||
sniff_on_connection_fail=True,
|
sniff_on_connection_fail=True,
|
||||||
@@ -398,9 +402,11 @@ class TestTransport:
|
|||||||
assert "http://1.1.1.1:123" == t.get_connection().host
|
assert "http://1.1.1.1:123" == t.get_connection().host
|
||||||
|
|
||||||
@patch("opensearchpy._async.transport.AsyncTransport.sniff_hosts")
|
@patch("opensearchpy._async.transport.AsyncTransport.sniff_hosts")
|
||||||
async def test_sniff_on_fail_failing_does_not_prevent_retires(self, sniff_hosts):
|
async def test_sniff_on_fail_failing_does_not_prevent_retires(
|
||||||
|
self, sniff_hosts: Any
|
||||||
|
) -> None:
|
||||||
sniff_hosts.side_effect = [TransportError("sniff failed")]
|
sniff_hosts.side_effect = [TransportError("sniff failed")]
|
||||||
t = AsyncTransport(
|
t: Any = AsyncTransport(
|
||||||
[{"exception": ConnectionError("abandon ship")}, {"data": CLUSTER_NODES}],
|
[{"exception": ConnectionError("abandon ship")}, {"data": CLUSTER_NODES}],
|
||||||
connection_class=DummyConnection,
|
connection_class=DummyConnection,
|
||||||
sniff_on_connection_fail=True,
|
sniff_on_connection_fail=True,
|
||||||
@@ -416,8 +422,8 @@ class TestTransport:
|
|||||||
assert 1 == len(conn_err.calls)
|
assert 1 == len(conn_err.calls)
|
||||||
assert 1 == len(conn_data.calls)
|
assert 1 == len(conn_data.calls)
|
||||||
|
|
||||||
async def test_sniff_after_n_seconds(self, event_loop) -> None:
|
async def test_sniff_after_n_seconds(self, event_loop: Any) -> None:
|
||||||
t = AsyncTransport(
|
t: Any = AsyncTransport(
|
||||||
[{"data": CLUSTER_NODES}],
|
[{"data": CLUSTER_NODES}],
|
||||||
connection_class=DummyConnection,
|
connection_class=DummyConnection,
|
||||||
sniffer_timeout=5,
|
sniffer_timeout=5,
|
||||||
@@ -440,7 +446,7 @@ class TestTransport:
|
|||||||
async def test_sniff_7x_publish_host(self) -> None:
|
async def test_sniff_7x_publish_host(self) -> None:
|
||||||
# Test the response shaped when a 7.x node has publish_host set
|
# Test the response shaped when a 7.x node has publish_host set
|
||||||
# and the returend data is shaped in the fqdn/ip:port format.
|
# and the returend data is shaped in the fqdn/ip:port format.
|
||||||
t = AsyncTransport(
|
t: Any = AsyncTransport(
|
||||||
[{"data": CLUSTER_NODES_7x_PUBLISH_HOST}],
|
[{"data": CLUSTER_NODES_7x_PUBLISH_HOST}],
|
||||||
connection_class=DummyConnection,
|
connection_class=DummyConnection,
|
||||||
sniff_timeout=42,
|
sniff_timeout=42,
|
||||||
@@ -454,22 +460,24 @@ class TestTransport:
|
|||||||
}
|
}
|
||||||
|
|
||||||
async def test_transport_close_closes_all_pool_connections(self) -> None:
|
async def test_transport_close_closes_all_pool_connections(self) -> None:
|
||||||
t = AsyncTransport([{}], connection_class=DummyConnection)
|
t1: Any = AsyncTransport([{}], connection_class=DummyConnection)
|
||||||
await t._async_call()
|
await t1._async_call()
|
||||||
|
|
||||||
assert not any([conn.closed for conn in t.connection_pool.connections])
|
assert not any([conn.closed for conn in t1.connection_pool.connections])
|
||||||
await t.close()
|
await t1.close()
|
||||||
assert all([conn.closed for conn in t.connection_pool.connections])
|
assert all([conn.closed for conn in t1.connection_pool.connections])
|
||||||
|
|
||||||
t = AsyncTransport([{}, {}], connection_class=DummyConnection)
|
t2: Any = AsyncTransport([{}, {}], connection_class=DummyConnection)
|
||||||
await t._async_call()
|
await t2._async_call()
|
||||||
|
|
||||||
assert not any([conn.closed for conn in t.connection_pool.connections])
|
assert not any([conn.closed for conn in t2.connection_pool.connections])
|
||||||
await t.close()
|
await t2.close()
|
||||||
assert all([conn.closed for conn in t.connection_pool.connections])
|
assert all([conn.closed for conn in t2.connection_pool.connections])
|
||||||
|
|
||||||
async def test_sniff_on_start_error_if_no_sniffed_hosts(self, event_loop) -> None:
|
async def test_sniff_on_start_error_if_no_sniffed_hosts(
|
||||||
t = AsyncTransport(
|
self, event_loop: Any
|
||||||
|
) -> None:
|
||||||
|
t: Any = AsyncTransport(
|
||||||
[
|
[
|
||||||
{"data": ""},
|
{"data": ""},
|
||||||
{"data": ""},
|
{"data": ""},
|
||||||
@@ -485,8 +493,10 @@ class TestTransport:
|
|||||||
await t._async_call()
|
await t._async_call()
|
||||||
assert str(e.value) == "TransportError(N/A, 'Unable to sniff hosts.')"
|
assert str(e.value) == "TransportError(N/A, 'Unable to sniff hosts.')"
|
||||||
|
|
||||||
async def test_sniff_on_start_waits_for_sniff_to_complete(self, event_loop):
|
async def test_sniff_on_start_waits_for_sniff_to_complete(
|
||||||
t = AsyncTransport(
|
self, event_loop: Any
|
||||||
|
) -> None:
|
||||||
|
t: Any = AsyncTransport(
|
||||||
[
|
[
|
||||||
{"delay": 1, "data": ""},
|
{"delay": 1, "data": ""},
|
||||||
{"delay": 1, "data": ""},
|
{"delay": 1, "data": ""},
|
||||||
@@ -521,8 +531,10 @@ class TestTransport:
|
|||||||
# and then resolved immediately after.
|
# and then resolved immediately after.
|
||||||
assert 1 <= duration < 2
|
assert 1 <= duration < 2
|
||||||
|
|
||||||
async def test_sniff_on_start_close_unlocks_async_calls(self, event_loop):
|
async def test_sniff_on_start_close_unlocks_async_calls(
|
||||||
t = AsyncTransport(
|
self, event_loop: Any
|
||||||
|
) -> None:
|
||||||
|
t: Any = AsyncTransport(
|
||||||
[
|
[
|
||||||
{"delay": 10, "data": CLUSTER_NODES},
|
{"delay": 10, "data": CLUSTER_NODES},
|
||||||
],
|
],
|
||||||
@@ -559,7 +571,7 @@ class TestTransport:
|
|||||||
"""
|
"""
|
||||||
amt_hosts = 4
|
amt_hosts = 4
|
||||||
hosts = [{"host": "localhost", "port": 9092}] * amt_hosts
|
hosts = [{"host": "localhost", "port": 9092}] * amt_hosts
|
||||||
t = AsyncTransport(
|
t: Any = AsyncTransport(
|
||||||
hosts=hosts,
|
hosts=hosts,
|
||||||
)
|
)
|
||||||
await t._async_init()
|
await t._async_init()
|
||||||
@@ -577,7 +589,7 @@ class TestTransport:
|
|||||||
"""
|
"""
|
||||||
amt_hosts = 4
|
amt_hosts = 4
|
||||||
hosts = [{"host": "localhost", "port": 9092}] * amt_hosts
|
hosts = [{"host": "localhost", "port": 9092}] * amt_hosts
|
||||||
t = AsyncTransport(
|
t: Any = AsyncTransport(
|
||||||
hosts=hosts,
|
hosts=hosts,
|
||||||
connection_class=AIOHttpConnection,
|
connection_class=AIOHttpConnection,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -27,21 +27,30 @@
|
|||||||
|
|
||||||
|
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from unittest import SkipTest # noqa: F401
|
from typing import Any, Sequence
|
||||||
from unittest import TestCase
|
from unittest import SkipTest, TestCase
|
||||||
|
|
||||||
from opensearchpy import OpenSearch
|
from opensearchpy import OpenSearch
|
||||||
|
|
||||||
|
|
||||||
class DummyTransport(object):
|
class DummyTransport(object):
|
||||||
def __init__(self, hosts, responses=None, **kwargs) -> None:
|
def __init__(
|
||||||
|
self, hosts: Sequence[str], responses: Any = None, **kwargs: Any
|
||||||
|
) -> None:
|
||||||
self.hosts = hosts
|
self.hosts = hosts
|
||||||
self.responses = responses
|
self.responses = responses
|
||||||
self.call_count = 0
|
self.call_count: int = 0
|
||||||
self.calls = defaultdict(list)
|
self.calls: Any = defaultdict(list)
|
||||||
|
|
||||||
def perform_request(self, method, url, params=None, headers=None, body=None):
|
def perform_request(
|
||||||
resp = 200, {}
|
self,
|
||||||
|
method: str,
|
||||||
|
url: str,
|
||||||
|
params: Any = None,
|
||||||
|
headers: Any = None,
|
||||||
|
body: Any = None,
|
||||||
|
) -> Any:
|
||||||
|
resp: Any = (200, {})
|
||||||
if self.responses:
|
if self.responses:
|
||||||
resp = self.responses[self.call_count]
|
resp = self.responses[self.call_count]
|
||||||
self.call_count += 1
|
self.call_count += 1
|
||||||
@@ -52,12 +61,12 @@ class DummyTransport(object):
|
|||||||
class OpenSearchTestCase(TestCase):
|
class OpenSearchTestCase(TestCase):
|
||||||
def setUp(self) -> None:
|
def setUp(self) -> None:
|
||||||
super(OpenSearchTestCase, self).setUp()
|
super(OpenSearchTestCase, self).setUp()
|
||||||
self.client = OpenSearch(transport_class=DummyTransport)
|
self.client: Any = OpenSearch(transport_class=DummyTransport) # type: ignore
|
||||||
|
|
||||||
def assert_call_count_equals(self, count) -> None:
|
def assert_call_count_equals(self, count: int) -> None:
|
||||||
self.assertEqual(count, self.client.transport.call_count)
|
self.assertEqual(count, self.client.transport.call_count)
|
||||||
|
|
||||||
def assert_url_called(self, method, url, count: int = 1):
|
def assert_url_called(self, method: str, url: str, count: int = 1) -> Any:
|
||||||
self.assertIn((method, url), self.client.transport.calls)
|
self.assertIn((method, url), self.client.transport.calls)
|
||||||
calls = self.client.transport.calls[(method, url)]
|
calls = self.client.transport.calls[(method, url)]
|
||||||
self.assertEqual(count, len(calls))
|
self.assertEqual(count, len(calls))
|
||||||
@@ -78,3 +87,6 @@ class TestOpenSearchTestCase(OpenSearchTestCase):
|
|||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
[({}, None, "body")], self.assert_url_called("DELETE", "/42", 1)
|
[({}, None, "body")], self.assert_url_called("DELETE", "/42", 1)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = ["SkipTest", "TestCase"]
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ class TestPluginsClient(TestCase):
|
|||||||
def test_plugins_client(self) -> None:
|
def test_plugins_client(self) -> None:
|
||||||
with self.assertWarns(Warning) as w:
|
with self.assertWarns(Warning) as w:
|
||||||
client = OpenSearch()
|
client = OpenSearch()
|
||||||
client.plugins.__init__(client) # double-init
|
# double-init
|
||||||
|
client.plugins.__init__(client) # type: ignore
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
str(w.warnings[0].message),
|
str(w.warnings[0].message),
|
||||||
"Cannot load `alerting` directly to OpenSearch as it already exists. Use `OpenSearch.plugin.alerting` instead.",
|
"Cannot load `alerting` directly to OpenSearch as it already exists. Use `OpenSearch.plugin.alerting` instead.",
|
||||||
|
|||||||
@@ -28,17 +28,19 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from opensearchpy.client.utils import _bulk_body, _escape, _make_path, query_params
|
from opensearchpy.client.utils import _bulk_body, _escape, _make_path, query_params
|
||||||
|
|
||||||
from ..test_cases import TestCase
|
from ..test_cases import TestCase
|
||||||
|
|
||||||
|
|
||||||
class TestQueryParams(TestCase):
|
class TestQueryParams(TestCase):
|
||||||
def setup_method(self, _) -> None:
|
def setup_method(self, _: Any) -> None:
|
||||||
self.calls = []
|
self.calls: Any = []
|
||||||
|
|
||||||
@query_params("simple_param")
|
@query_params("simple_param")
|
||||||
def func_to_wrap(self, *args, **kwargs) -> None:
|
def func_to_wrap(self, *args: Any, **kwargs: Any) -> None:
|
||||||
self.calls.append((args, kwargs))
|
self.calls.append((args, kwargs))
|
||||||
|
|
||||||
def test_handles_params(self) -> None:
|
def test_handles_params(self) -> None:
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ class TestBaseConnection(TestCase):
|
|||||||
|
|
||||||
self.assertEqual([str(w.message) for w in warn], ["warning", "folded"])
|
self.assertEqual([str(w.message) for w in warn], ["warning", "folded"])
|
||||||
|
|
||||||
def test_ipv6_host_and_port(self):
|
def test_ipv6_host_and_port(self) -> None:
|
||||||
for kwargs, expected_host in [
|
for kwargs, expected_host in [
|
||||||
({"host": "::1"}, "http://[::1]:9200"),
|
({"host": "::1"}, "http://[::1]:9200"),
|
||||||
({"host": "::1", "port": 443}, "http://[::1]:443"),
|
({"host": "::1", "port": 443}, "http://[::1]:443"),
|
||||||
@@ -96,7 +96,7 @@ class TestBaseConnection(TestCase):
|
|||||||
({"host": "127.0.0.1", "port": 1234}, "http://127.0.0.1:1234"),
|
({"host": "127.0.0.1", "port": 1234}, "http://127.0.0.1:1234"),
|
||||||
({"host": "localhost", "use_ssl": True}, "https://localhost:9200"),
|
({"host": "localhost", "use_ssl": True}, "https://localhost:9200"),
|
||||||
]:
|
]:
|
||||||
conn = Connection(**kwargs)
|
conn = Connection(**kwargs) # type: ignore
|
||||||
assert conn.host == expected_host
|
assert conn.host == expected_host
|
||||||
|
|
||||||
def test_compatibility_accept_header(self) -> None:
|
def test_compatibility_accept_header(self) -> None:
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import json
|
|||||||
import re
|
import re
|
||||||
import uuid
|
import uuid
|
||||||
import warnings
|
import warnings
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from mock import Mock, patch
|
from mock import Mock, patch
|
||||||
@@ -49,24 +50,27 @@ from ..test_cases import TestCase
|
|||||||
|
|
||||||
class TestRequestsHttpConnection(TestCase):
|
class TestRequestsHttpConnection(TestCase):
|
||||||
def _get_mock_connection(
|
def _get_mock_connection(
|
||||||
self, connection_params={}, status_code: int = 200, response_body: bytes = b"{}"
|
self,
|
||||||
):
|
connection_params: Any = {},
|
||||||
|
status_code: int = 200,
|
||||||
|
response_body: bytes = b"{}",
|
||||||
|
) -> Any:
|
||||||
con = RequestsHttpConnection(**connection_params)
|
con = RequestsHttpConnection(**connection_params)
|
||||||
|
|
||||||
def _dummy_send(*args, **kwargs):
|
def _dummy_send(*args: Any, **kwargs: Any) -> Any:
|
||||||
dummy_response = Mock()
|
dummy_response = Mock()
|
||||||
dummy_response.headers = {}
|
dummy_response.headers = {}
|
||||||
dummy_response.status_code = status_code
|
dummy_response.status_code = status_code
|
||||||
dummy_response.content = response_body
|
dummy_response.content = response_body
|
||||||
dummy_response.request = args[0]
|
dummy_response.request = args[0]
|
||||||
dummy_response.cookies = {}
|
dummy_response.cookies = {}
|
||||||
_dummy_send.call_args = (args, kwargs)
|
_dummy_send.call_args = (args, kwargs) # type: ignore
|
||||||
return dummy_response
|
return dummy_response
|
||||||
|
|
||||||
con.session.send = _dummy_send
|
con.session.send = _dummy_send # type: ignore
|
||||||
return con
|
return con
|
||||||
|
|
||||||
def _get_request(self, connection, *args, **kwargs):
|
def _get_request(self, connection: Any, *args: Any, **kwargs: Any) -> Any:
|
||||||
if "body" in kwargs:
|
if "body" in kwargs:
|
||||||
kwargs["body"] = kwargs["body"].encode("utf-8")
|
kwargs["body"] = kwargs["body"].encode("utf-8")
|
||||||
|
|
||||||
@@ -237,14 +241,14 @@ class TestRequestsHttpConnection(TestCase):
|
|||||||
self.assertRaises(RequestError, con.perform_request, "GET", "/", {}, "")
|
self.assertRaises(RequestError, con.perform_request, "GET", "/", {}, "")
|
||||||
|
|
||||||
@patch("opensearchpy.connection.base.logger")
|
@patch("opensearchpy.connection.base.logger")
|
||||||
def test_head_with_404_doesnt_get_logged(self, logger) -> None:
|
def test_head_with_404_doesnt_get_logged(self, logger: Any) -> None:
|
||||||
con = self._get_mock_connection(status_code=404)
|
con = self._get_mock_connection(status_code=404)
|
||||||
self.assertRaises(NotFoundError, con.perform_request, "HEAD", "/", {}, "")
|
self.assertRaises(NotFoundError, con.perform_request, "HEAD", "/", {}, "")
|
||||||
self.assertEqual(0, logger.warning.call_count)
|
self.assertEqual(0, logger.warning.call_count)
|
||||||
|
|
||||||
@patch("opensearchpy.connection.base.tracer")
|
@patch("opensearchpy.connection.base.tracer")
|
||||||
@patch("opensearchpy.connection.base.logger")
|
@patch("opensearchpy.connection.base.logger")
|
||||||
def test_failed_request_logs_and_traces(self, logger, tracer) -> None:
|
def test_failed_request_logs_and_traces(self, logger: Any, tracer: Any) -> None:
|
||||||
con = self._get_mock_connection(
|
con = self._get_mock_connection(
|
||||||
response_body=b'{"answer": 42}', status_code=500
|
response_body=b'{"answer": 42}', status_code=500
|
||||||
)
|
)
|
||||||
@@ -272,7 +276,7 @@ class TestRequestsHttpConnection(TestCase):
|
|||||||
|
|
||||||
@patch("opensearchpy.connection.base.tracer")
|
@patch("opensearchpy.connection.base.tracer")
|
||||||
@patch("opensearchpy.connection.base.logger")
|
@patch("opensearchpy.connection.base.logger")
|
||||||
def test_success_logs_and_traces(self, logger, tracer) -> None:
|
def test_success_logs_and_traces(self, logger: Any, tracer: Any) -> None:
|
||||||
con = self._get_mock_connection(response_body=b"""{"answer": "that's it!"}""")
|
con = self._get_mock_connection(response_body=b"""{"answer": "that's it!"}""")
|
||||||
status, headers, data = con.perform_request(
|
status, headers, data = con.perform_request(
|
||||||
"GET",
|
"GET",
|
||||||
@@ -311,7 +315,7 @@ class TestRequestsHttpConnection(TestCase):
|
|||||||
self.assertEqual('< {"answer": "that\'s it!"}', resp[0][0] % resp[0][1:])
|
self.assertEqual('< {"answer": "that\'s it!"}', resp[0][0] % resp[0][1:])
|
||||||
|
|
||||||
@patch("opensearchpy.connection.base.logger")
|
@patch("opensearchpy.connection.base.logger")
|
||||||
def test_uncompressed_body_logged(self, logger) -> None:
|
def test_uncompressed_body_logged(self, logger: Any) -> None:
|
||||||
con = self._get_mock_connection(connection_params={"http_compress": True})
|
con = self._get_mock_connection(connection_params={"http_compress": True})
|
||||||
con.perform_request("GET", "/", body=b'{"example": "body"}')
|
con.perform_request("GET", "/", body=b'{"example": "body"}')
|
||||||
|
|
||||||
@@ -366,7 +370,7 @@ class TestRequestsHttpConnection(TestCase):
|
|||||||
self.assertEqual(request.headers["authorization"], "Basic dXNlcm5hbWU6c2VjcmV0")
|
self.assertEqual(request.headers["authorization"], "Basic dXNlcm5hbWU6c2VjcmV0")
|
||||||
|
|
||||||
@patch("opensearchpy.connection.base.tracer")
|
@patch("opensearchpy.connection.base.tracer")
|
||||||
def test_url_prefix(self, tracer) -> None:
|
def test_url_prefix(self, tracer: Any) -> None:
|
||||||
con = self._get_mock_connection({"url_prefix": "/some-prefix/"})
|
con = self._get_mock_connection({"url_prefix": "/some-prefix/"})
|
||||||
request = self._get_request(
|
request = self._get_request(
|
||||||
con, "GET", "/_search", body='{"answer": 42}', timeout=0.1
|
con, "GET", "/_search", body='{"answer": 42}', timeout=0.1
|
||||||
@@ -392,16 +396,16 @@ class TestRequestsHttpConnection(TestCase):
|
|||||||
def test_recursion_error_reraised(self) -> None:
|
def test_recursion_error_reraised(self) -> None:
|
||||||
conn = RequestsHttpConnection()
|
conn = RequestsHttpConnection()
|
||||||
|
|
||||||
def send_raise(*_, **__):
|
def send_raise(*_: Any, **__: Any) -> Any:
|
||||||
raise RecursionError("Wasn't modified!")
|
raise RecursionError("Wasn't modified!")
|
||||||
|
|
||||||
conn.session.send = send_raise
|
conn.session.send = send_raise # type: ignore
|
||||||
|
|
||||||
with pytest.raises(RecursionError) as e:
|
with pytest.raises(RecursionError) as e:
|
||||||
conn.perform_request("GET", "/")
|
conn.perform_request("GET", "/")
|
||||||
assert str(e.value) == "Wasn't modified!"
|
assert str(e.value) == "Wasn't modified!"
|
||||||
|
|
||||||
def mock_session(self):
|
def mock_session(self) -> Any:
|
||||||
access_key = uuid.uuid4().hex
|
access_key = uuid.uuid4().hex
|
||||||
secret_key = uuid.uuid4().hex
|
secret_key = uuid.uuid4().hex
|
||||||
token = uuid.uuid4().hex
|
token = uuid.uuid4().hex
|
||||||
@@ -448,7 +452,7 @@ class TestRequestsHttpConnection(TestCase):
|
|||||||
self.assertIn("X-Amz-Security-Token", prepared_request.headers)
|
self.assertIn("X-Amz-Security-Token", prepared_request.headers)
|
||||||
|
|
||||||
@patch("opensearchpy.helpers.signer.AWSV4Signer.sign")
|
@patch("opensearchpy.helpers.signer.AWSV4Signer.sign")
|
||||||
def test_aws_signer_signs_with_query_string(self, mock_sign) -> None:
|
def test_aws_signer_signs_with_query_string(self, mock_sign: Any) -> None:
|
||||||
region = "us-west-1"
|
region = "us-west-1"
|
||||||
service = "aoss"
|
service = "aoss"
|
||||||
|
|
||||||
@@ -469,6 +473,9 @@ class TestRequestsHttpConnection(TestCase):
|
|||||||
|
|
||||||
|
|
||||||
class TestRequestsConnectionRedirect:
|
class TestRequestsConnectionRedirect:
|
||||||
|
server1: TestHTTPServer
|
||||||
|
server2: TestHTTPServer
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setup_class(cls) -> None:
|
def setup_class(cls) -> None:
|
||||||
# Start servers
|
# Start servers
|
||||||
@@ -505,7 +512,7 @@ class TestRequestsConnectionRedirect:
|
|||||||
|
|
||||||
|
|
||||||
class TestSignerWithFrozenCredentials(TestRequestsHttpConnection):
|
class TestSignerWithFrozenCredentials(TestRequestsHttpConnection):
|
||||||
def mock_session(self):
|
def mock_session(self) -> Any:
|
||||||
access_key = uuid.uuid4().hex
|
access_key = uuid.uuid4().hex
|
||||||
secret_key = uuid.uuid4().hex
|
secret_key = uuid.uuid4().hex
|
||||||
token = uuid.uuid4().hex
|
token = uuid.uuid4().hex
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import warnings
|
|||||||
from gzip import GzipFile
|
from gzip import GzipFile
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from platform import python_version
|
from platform import python_version
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
import urllib3
|
import urllib3
|
||||||
@@ -45,15 +46,17 @@ from ..test_cases import SkipTest, TestCase
|
|||||||
|
|
||||||
|
|
||||||
class TestUrllib3HttpConnection(TestCase):
|
class TestUrllib3HttpConnection(TestCase):
|
||||||
def _get_mock_connection(self, connection_params={}, response_body: bytes = b"{}"):
|
def _get_mock_connection(
|
||||||
|
self, connection_params: Any = {}, response_body: bytes = b"{}"
|
||||||
|
) -> Any:
|
||||||
con = Urllib3HttpConnection(**connection_params)
|
con = Urllib3HttpConnection(**connection_params)
|
||||||
|
|
||||||
def _dummy_urlopen(*args, **kwargs):
|
def _dummy_urlopen(*args: Any, **kwargs: Any) -> Any:
|
||||||
dummy_response = Mock()
|
dummy_response = Mock()
|
||||||
dummy_response.headers = HTTPHeaderDict({})
|
dummy_response.headers = HTTPHeaderDict({})
|
||||||
dummy_response.status = 200
|
dummy_response.status = 200
|
||||||
dummy_response.data = response_body
|
dummy_response.data = response_body
|
||||||
_dummy_urlopen.call_args = (args, kwargs)
|
_dummy_urlopen.call_args = (args, kwargs) # type: ignore
|
||||||
return dummy_response
|
return dummy_response
|
||||||
|
|
||||||
con.pool.urlopen = _dummy_urlopen
|
con.pool.urlopen = _dummy_urlopen
|
||||||
@@ -181,7 +184,7 @@ class TestUrllib3HttpConnection(TestCase):
|
|||||||
"urllib3.HTTPConnectionPool.urlopen",
|
"urllib3.HTTPConnectionPool.urlopen",
|
||||||
return_value=Mock(status=200, headers=HTTPHeaderDict({}), data=b"{}"),
|
return_value=Mock(status=200, headers=HTTPHeaderDict({}), data=b"{}"),
|
||||||
)
|
)
|
||||||
def test_aws_signer_as_http_auth_adds_headers(self, mock_open) -> None:
|
def test_aws_signer_as_http_auth_adds_headers(self, mock_open: Any) -> None:
|
||||||
from opensearchpy.helpers.signer import Urllib3AWSV4SignerAuth
|
from opensearchpy.helpers.signer import Urllib3AWSV4SignerAuth
|
||||||
|
|
||||||
auth = Urllib3AWSV4SignerAuth(self.mock_session(), "us-west-2")
|
auth = Urllib3AWSV4SignerAuth(self.mock_session(), "us-west-2")
|
||||||
@@ -247,7 +250,7 @@ class TestUrllib3HttpConnection(TestCase):
|
|||||||
self.assertIn("X-Amz-Date", headers)
|
self.assertIn("X-Amz-Date", headers)
|
||||||
self.assertIn("X-Amz-Security-Token", headers)
|
self.assertIn("X-Amz-Security-Token", headers)
|
||||||
|
|
||||||
def mock_session(self):
|
def mock_session(self) -> Any:
|
||||||
access_key = uuid.uuid4().hex
|
access_key = uuid.uuid4().hex
|
||||||
secret_key = uuid.uuid4().hex
|
secret_key = uuid.uuid4().hex
|
||||||
token = uuid.uuid4().hex
|
token = uuid.uuid4().hex
|
||||||
@@ -290,6 +293,7 @@ class TestUrllib3HttpConnection(TestCase):
|
|||||||
self.assertEqual(0, len(w))
|
self.assertEqual(0, len(w))
|
||||||
|
|
||||||
def test_warns_if_using_non_default_ssl_kwargs_with_ssl_context(self) -> None:
|
def test_warns_if_using_non_default_ssl_kwargs_with_ssl_context(self) -> None:
|
||||||
|
kwargs: Any
|
||||||
for kwargs in (
|
for kwargs in (
|
||||||
{"ssl_show_warn": False},
|
{"ssl_show_warn": False},
|
||||||
{"ssl_show_warn": True},
|
{"ssl_show_warn": True},
|
||||||
@@ -325,7 +329,7 @@ class TestUrllib3HttpConnection(TestCase):
|
|||||||
self.assertIsNone(c.pool.ca_certs)
|
self.assertIsNone(c.pool.ca_certs)
|
||||||
|
|
||||||
@patch("opensearchpy.connection.base.logger")
|
@patch("opensearchpy.connection.base.logger")
|
||||||
def test_uncompressed_body_logged(self, logger) -> None:
|
def test_uncompressed_body_logged(self, logger: Any) -> None:
|
||||||
con = self._get_mock_connection(connection_params={"http_compress": True})
|
con = self._get_mock_connection(connection_params={"http_compress": True})
|
||||||
con.perform_request("GET", "/", body=b'{"example": "body"}')
|
con.perform_request("GET", "/", body=b'{"example": "body"}')
|
||||||
|
|
||||||
@@ -344,7 +348,7 @@ class TestUrllib3HttpConnection(TestCase):
|
|||||||
def test_recursion_error_reraised(self) -> None:
|
def test_recursion_error_reraised(self) -> None:
|
||||||
conn = Urllib3HttpConnection()
|
conn = Urllib3HttpConnection()
|
||||||
|
|
||||||
def urlopen_raise(*_, **__):
|
def urlopen_raise(*_: Any, **__: Any) -> Any:
|
||||||
raise RecursionError("Wasn't modified!")
|
raise RecursionError("Wasn't modified!")
|
||||||
|
|
||||||
conn.pool.urlopen = urlopen_raise
|
conn.pool.urlopen = urlopen_raise
|
||||||
@@ -355,7 +359,7 @@ class TestUrllib3HttpConnection(TestCase):
|
|||||||
|
|
||||||
|
|
||||||
class TestSignerWithFrozenCredentials(TestUrllib3HttpConnection):
|
class TestSignerWithFrozenCredentials(TestUrllib3HttpConnection):
|
||||||
def mock_session(self):
|
def mock_session(self) -> Any:
|
||||||
access_key = uuid.uuid4().hex
|
access_key = uuid.uuid4().hex
|
||||||
secret_key = uuid.uuid4().hex
|
secret_key = uuid.uuid4().hex
|
||||||
token = uuid.uuid4().hex
|
token = uuid.uuid4().hex
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
|
|
||||||
import time
|
import time
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from opensearchpy.connection import Connection
|
from opensearchpy.connection import Connection
|
||||||
from opensearchpy.connection_pool import (
|
from opensearchpy.connection_pool import (
|
||||||
@@ -57,7 +58,7 @@ class TestConnectionPool(TestCase):
|
|||||||
connections.add(pool.get_connection())
|
connections.add(pool.get_connection())
|
||||||
self.assertEqual(connections, set(range(100)))
|
self.assertEqual(connections, set(range(100)))
|
||||||
|
|
||||||
def test_disable_shuffling(self):
|
def test_disable_shuffling(self) -> None:
|
||||||
pool = ConnectionPool([(x, {}) for x in range(100)], randomize_hosts=False)
|
pool = ConnectionPool([(x, {}) for x in range(100)], randomize_hosts=False)
|
||||||
|
|
||||||
connections = []
|
connections = []
|
||||||
@@ -65,9 +66,9 @@ class TestConnectionPool(TestCase):
|
|||||||
connections.append(pool.get_connection())
|
connections.append(pool.get_connection())
|
||||||
self.assertEqual(connections, list(range(100)))
|
self.assertEqual(connections, list(range(100)))
|
||||||
|
|
||||||
def test_selectors_have_access_to_connection_opts(self):
|
def test_selectors_have_access_to_connection_opts(self) -> None:
|
||||||
class MySelector(RoundRobinSelector):
|
class MySelector(RoundRobinSelector):
|
||||||
def select(self, connections):
|
def select(self, connections: Any) -> Any:
|
||||||
return self.connection_opts[
|
return self.connection_opts[
|
||||||
super(MySelector, self).select(connections)
|
super(MySelector, self).select(connections)
|
||||||
]["actual"]
|
]["actual"]
|
||||||
|
|||||||
@@ -26,24 +26,26 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from mock import Mock
|
from mock import Mock
|
||||||
from pytest import fixture
|
from pytest import fixture
|
||||||
|
|
||||||
from opensearchpy.connection.connections import add_connection, connections
|
from opensearchpy.connection.connections import add_connection, connections
|
||||||
|
|
||||||
|
|
||||||
@fixture
|
@fixture # type: ignore
|
||||||
def mock_client(dummy_response):
|
def mock_client(dummy_response: Any) -> Any:
|
||||||
client = Mock()
|
client = Mock()
|
||||||
client.search.return_value = dummy_response
|
client.search.return_value = dummy_response
|
||||||
add_connection("mock", client)
|
add_connection("mock", client)
|
||||||
yield client
|
yield client
|
||||||
connections._conn = {}
|
connections._conns = {}
|
||||||
connections._kwargs = {}
|
connections._kwargs = {}
|
||||||
|
|
||||||
|
|
||||||
@fixture
|
@fixture # type: ignore
|
||||||
def dummy_response():
|
def dummy_response() -> Any:
|
||||||
return {
|
return {
|
||||||
"_shards": {"failed": 0, "successful": 10, "total": 10},
|
"_shards": {"failed": 0, "successful": 10, "total": 10},
|
||||||
"hits": {
|
"hits": {
|
||||||
@@ -91,8 +93,8 @@ def dummy_response():
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@fixture
|
@fixture # type: ignore
|
||||||
def aggs_search():
|
def aggs_search() -> Any:
|
||||||
from opensearchpy import Search
|
from opensearchpy import Search
|
||||||
|
|
||||||
s = Search(index="flat-git")
|
s = Search(index="flat-git")
|
||||||
@@ -106,8 +108,8 @@ def aggs_search():
|
|||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
||||||
@fixture
|
@fixture # type: ignore
|
||||||
def aggs_data():
|
def aggs_data() -> Any:
|
||||||
return {
|
return {
|
||||||
"took": 4,
|
"took": 4,
|
||||||
"timed_out": False,
|
"timed_out": False,
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import mock
|
import mock
|
||||||
import pytest
|
import pytest
|
||||||
@@ -40,19 +41,19 @@ from ..test_cases import TestCase
|
|||||||
lock_side_effect = threading.Lock()
|
lock_side_effect = threading.Lock()
|
||||||
|
|
||||||
|
|
||||||
def mock_process_bulk_chunk(*args, **kwargs):
|
def mock_process_bulk_chunk(*args: Any, **kwargs: Any) -> Any:
|
||||||
"""
|
"""
|
||||||
Threadsafe way of mocking process bulk chunk:
|
Threadsafe way of mocking process bulk chunk:
|
||||||
https://stackoverflow.com/questions/39332139/thread-safe-version-of-mock-call-count
|
https://stackoverflow.com/questions/39332139/thread-safe-version-of-mock-call-count
|
||||||
"""
|
"""
|
||||||
|
|
||||||
with lock_side_effect:
|
with lock_side_effect:
|
||||||
mock_process_bulk_chunk.call_count += 1
|
mock_process_bulk_chunk.call_count += 1 # type: ignore
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
mock_process_bulk_chunk.call_count = 0
|
mock_process_bulk_chunk.call_count = 0 # type: ignore
|
||||||
|
|
||||||
|
|
||||||
class TestParallelBulk(TestCase):
|
class TestParallelBulk(TestCase):
|
||||||
@@ -60,21 +61,21 @@ class TestParallelBulk(TestCase):
|
|||||||
"opensearchpy.helpers.actions._process_bulk_chunk",
|
"opensearchpy.helpers.actions._process_bulk_chunk",
|
||||||
side_effect=mock_process_bulk_chunk,
|
side_effect=mock_process_bulk_chunk,
|
||||||
)
|
)
|
||||||
def test_all_chunks_sent(self, _process_bulk_chunk) -> None:
|
def test_all_chunks_sent(self, _process_bulk_chunk: Any) -> None:
|
||||||
actions = ({"x": i} for i in range(100))
|
actions = ({"x": i} for i in range(100))
|
||||||
list(helpers.parallel_bulk(OpenSearch(), actions, chunk_size=2))
|
list(helpers.parallel_bulk(OpenSearch(), actions, chunk_size=2))
|
||||||
|
|
||||||
self.assertEqual(50, mock_process_bulk_chunk.call_count)
|
self.assertEqual(50, mock_process_bulk_chunk.call_count) # type: ignore
|
||||||
|
|
||||||
@pytest.mark.skip
|
@pytest.mark.skip # type: ignore
|
||||||
@mock.patch(
|
@mock.patch(
|
||||||
"opensearchpy.helpers.actions._process_bulk_chunk",
|
"opensearchpy.helpers.actions._process_bulk_chunk",
|
||||||
# make sure we spend some time in the thread
|
# make sure we spend some time in the thread
|
||||||
side_effect=lambda *a: [
|
side_effect=lambda *a: [
|
||||||
(True, time.sleep(0.001) or threading.current_thread().ident)
|
(True, time.sleep(0.001) or threading.current_thread().ident) # type: ignore
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_chunk_sent_from_different_threads(self, _process_bulk_chunk) -> None:
|
def test_chunk_sent_from_different_threads(self, _process_bulk_chunk: Any) -> None:
|
||||||
actions = ({"x": i} for i in range(100))
|
actions = ({"x": i} for i in range(100))
|
||||||
results = list(
|
results = list(
|
||||||
helpers.parallel_bulk(OpenSearch(), actions, thread_count=10, chunk_size=2)
|
helpers.parallel_bulk(OpenSearch(), actions, thread_count=10, chunk_size=2)
|
||||||
@@ -83,8 +84,8 @@ class TestParallelBulk(TestCase):
|
|||||||
|
|
||||||
|
|
||||||
class TestChunkActions(TestCase):
|
class TestChunkActions(TestCase):
|
||||||
def setup_method(self, _) -> None:
|
def setup_method(self, _: Any) -> None:
|
||||||
self.actions = [({"index": {}}, {"some": u"datá", "i": i}) for i in range(100)] # fmt: skip
|
self.actions: Any = [({"index": {}}, {"some": u"datá", "i": i}) for i in range(100)] # fmt: skip
|
||||||
|
|
||||||
def test_expand_action(self) -> None:
|
def test_expand_action(self) -> None:
|
||||||
self.assertEqual(helpers.expand_action({}), ({"index": {}}, {}))
|
self.assertEqual(helpers.expand_action({}), ({"index": {}}, {}))
|
||||||
@@ -92,7 +93,7 @@ class TestChunkActions(TestCase):
|
|||||||
helpers.expand_action({"key": "val"}), ({"index": {}}, {"key": "val"})
|
helpers.expand_action({"key": "val"}), ({"index": {}}, {"key": "val"})
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_expand_action_actions(self):
|
def test_expand_action_actions(self) -> None:
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
helpers.expand_action(
|
helpers.expand_action(
|
||||||
{"_op_type": "delete", "_id": "id", "_index": "index"}
|
{"_op_type": "delete", "_id": "id", "_index": "index"}
|
||||||
@@ -154,7 +155,7 @@ class TestChunkActions(TestCase):
|
|||||||
({"index": {action_option: 0}}, {"key": "val"}),
|
({"index": {action_option: 0}}, {"key": "val"}),
|
||||||
)
|
)
|
||||||
|
|
||||||
def test__source_metadata_or_source(self):
|
def test__source_metadata_or_source(self) -> None:
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
helpers.expand_action({"_source": {"key": "val"}}),
|
helpers.expand_action({"_source": {"key": "val"}}),
|
||||||
({"index": {}}, {"key": "val"}),
|
({"index": {}}, {"key": "val"}),
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ def test_repr() -> None:
|
|||||||
assert "Terms(aggs={'max_score': Max(field='score')}, field='tags')" == repr(a)
|
assert "Terms(aggs={'max_score': Max(field='score')}, field='tags')" == repr(a)
|
||||||
|
|
||||||
|
|
||||||
def test_meta():
|
def test_meta() -> None:
|
||||||
max_score = aggs.Max(field="score")
|
max_score = aggs.Max(field="score")
|
||||||
a = aggs.A(
|
a = aggs.A(
|
||||||
"terms", field="tags", aggs={"max_score": max_score}, meta={"some": "metadata"}
|
"terms", field="tags", aggs={"max_score": max_score}, meta={"some": "metadata"}
|
||||||
@@ -66,7 +66,7 @@ def test_A_creates_proper_agg() -> None:
|
|||||||
assert a._params == {"field": "tags"}
|
assert a._params == {"field": "tags"}
|
||||||
|
|
||||||
|
|
||||||
def test_A_handles_nested_aggs_properly():
|
def test_A_handles_nested_aggs_properly() -> None:
|
||||||
max_score = aggs.Max(field="score")
|
max_score = aggs.Max(field="score")
|
||||||
a = aggs.A("terms", field="tags", aggs={"max_score": max_score})
|
a = aggs.A("terms", field="tags", aggs={"max_score": max_score})
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ def test_A_passes_aggs_through() -> None:
|
|||||||
assert aggs.A(a) is a
|
assert aggs.A(a) is a
|
||||||
|
|
||||||
|
|
||||||
def test_A_from_dict():
|
def test_A_from_dict() -> None:
|
||||||
d = {
|
d = {
|
||||||
"terms": {"field": "tags"},
|
"terms": {"field": "tags"},
|
||||||
"aggs": {"per_author": {"terms": {"field": "author.raw"}}},
|
"aggs": {"per_author": {"terms": {"field": "author.raw"}}},
|
||||||
@@ -95,7 +95,7 @@ def test_A_from_dict():
|
|||||||
assert a.aggs.per_author == aggs.A("terms", field="author.raw")
|
assert a.aggs.per_author == aggs.A("terms", field="author.raw")
|
||||||
|
|
||||||
|
|
||||||
def test_A_fails_with_incorrect_dict():
|
def test_A_fails_with_incorrect_dict() -> None:
|
||||||
correct_d = {
|
correct_d = {
|
||||||
"terms": {"field": "tags"},
|
"terms": {"field": "tags"},
|
||||||
"aggs": {"per_author": {"terms": {"field": "author.raw"}}},
|
"aggs": {"per_author": {"terms": {"field": "author.raw"}}},
|
||||||
@@ -148,7 +148,7 @@ def test_buckets_equals_counts_subaggs() -> None:
|
|||||||
assert a != b
|
assert a != b
|
||||||
|
|
||||||
|
|
||||||
def test_buckets_to_dict():
|
def test_buckets_to_dict() -> None:
|
||||||
a = aggs.Terms(field="tags")
|
a = aggs.Terms(field="tags")
|
||||||
a.bucket("per_author", "terms", field="author.raw")
|
a.bucket("per_author", "terms", field="author.raw")
|
||||||
|
|
||||||
@@ -189,7 +189,7 @@ def test_filter_can_be_instantiated_using_positional_args() -> None:
|
|||||||
assert a == aggs.A("filter", query.Q("term", f=42))
|
assert a == aggs.A("filter", query.Q("term", f=42))
|
||||||
|
|
||||||
|
|
||||||
def test_filter_aggregation_as_nested_agg():
|
def test_filter_aggregation_as_nested_agg() -> None:
|
||||||
a = aggs.Terms(field="tags")
|
a = aggs.Terms(field="tags")
|
||||||
a.bucket("filtered", "filter", query.Q("term", f=42))
|
a.bucket("filtered", "filter", query.Q("term", f=42))
|
||||||
|
|
||||||
@@ -199,7 +199,7 @@ def test_filter_aggregation_as_nested_agg():
|
|||||||
} == a.to_dict()
|
} == a.to_dict()
|
||||||
|
|
||||||
|
|
||||||
def test_filter_aggregation_with_nested_aggs():
|
def test_filter_aggregation_with_nested_aggs() -> None:
|
||||||
a = aggs.Filter(query.Q("term", f=42))
|
a = aggs.Filter(query.Q("term", f=42))
|
||||||
a.bucket("testing", "terms", field="tags")
|
a.bucket("testing", "terms", field="tags")
|
||||||
|
|
||||||
@@ -229,7 +229,7 @@ def test_filters_correctly_identifies_the_hash() -> None:
|
|||||||
assert a.filters.group_a == query.Q("term", group="a")
|
assert a.filters.group_a == query.Q("term", group="a")
|
||||||
|
|
||||||
|
|
||||||
def test_bucket_sort_agg():
|
def test_bucket_sort_agg() -> None:
|
||||||
bucket_sort_agg = aggs.BucketSort(sort=[{"total_sales": {"order": "desc"}}], size=3)
|
bucket_sort_agg = aggs.BucketSort(sort=[{"total_sales": {"order": "desc"}}], size=3)
|
||||||
assert bucket_sort_agg.to_dict() == {
|
assert bucket_sort_agg.to_dict() == {
|
||||||
"bucket_sort": {"sort": [{"total_sales": {"order": "desc"}}], "size": 3}
|
"bucket_sort": {"sort": [{"total_sales": {"order": "desc"}}], "size": 3}
|
||||||
@@ -254,7 +254,7 @@ def test_bucket_sort_agg():
|
|||||||
} == a.to_dict()
|
} == a.to_dict()
|
||||||
|
|
||||||
|
|
||||||
def test_bucket_sort_agg_only_trnunc():
|
def test_bucket_sort_agg_only_trnunc() -> None:
|
||||||
bucket_sort_agg = aggs.BucketSort(**{"from": 1, "size": 1})
|
bucket_sort_agg = aggs.BucketSort(**{"from": 1, "size": 1})
|
||||||
assert bucket_sort_agg.to_dict() == {"bucket_sort": {"from": 1, "size": 1}}
|
assert bucket_sort_agg.to_dict() == {"bucket_sort": {"from": 1, "size": 1}}
|
||||||
|
|
||||||
@@ -284,7 +284,7 @@ def test_boxplot_aggregation() -> None:
|
|||||||
assert {"boxplot": {"field": "load_time"}} == a.to_dict()
|
assert {"boxplot": {"field": "load_time"}} == a.to_dict()
|
||||||
|
|
||||||
|
|
||||||
def test_rare_terms_aggregation():
|
def test_rare_terms_aggregation() -> None:
|
||||||
a = aggs.RareTerms(field="the-field")
|
a = aggs.RareTerms(field="the-field")
|
||||||
a.bucket("total_sales", "sum", field="price")
|
a.bucket("total_sales", "sum", field="price")
|
||||||
a.bucket(
|
a.bucket(
|
||||||
@@ -316,7 +316,7 @@ def test_median_absolute_deviation_aggregation() -> None:
|
|||||||
assert {"median_absolute_deviation": {"field": "rating"}} == a.to_dict()
|
assert {"median_absolute_deviation": {"field": "rating"}} == a.to_dict()
|
||||||
|
|
||||||
|
|
||||||
def test_t_test_aggregation():
|
def test_t_test_aggregation() -> None:
|
||||||
a = aggs.TTest(
|
a = aggs.TTest(
|
||||||
a={"field": "startup_time_before"},
|
a={"field": "startup_time_before"},
|
||||||
b={"field": "startup_time_after"},
|
b={"field": "startup_time_after"},
|
||||||
@@ -332,14 +332,14 @@ def test_t_test_aggregation():
|
|||||||
} == a.to_dict()
|
} == a.to_dict()
|
||||||
|
|
||||||
|
|
||||||
def test_inference_aggregation():
|
def test_inference_aggregation() -> None:
|
||||||
a = aggs.Inference(model_id="model-id", buckets_path={"agg_name": "agg_name"})
|
a = aggs.Inference(model_id="model-id", buckets_path={"agg_name": "agg_name"})
|
||||||
assert {
|
assert {
|
||||||
"inference": {"buckets_path": {"agg_name": "agg_name"}, "model_id": "model-id"}
|
"inference": {"buckets_path": {"agg_name": "agg_name"}, "model_id": "model-id"}
|
||||||
} == a.to_dict()
|
} == a.to_dict()
|
||||||
|
|
||||||
|
|
||||||
def test_moving_percentiles_aggregation():
|
def test_moving_percentiles_aggregation() -> None:
|
||||||
a = aggs.DateHistogram()
|
a = aggs.DateHistogram()
|
||||||
a.bucket("the_percentile", "percentiles", field="price", percents=[1.0, 99.0])
|
a.bucket("the_percentile", "percentiles", field="price", percents=[1.0, 99.0])
|
||||||
a.pipeline(
|
a.pipeline(
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ def test_analyzer_serializes_as_name() -> None:
|
|||||||
assert "my_analyzer" == a.to_dict()
|
assert "my_analyzer" == a.to_dict()
|
||||||
|
|
||||||
|
|
||||||
def test_analyzer_has_definition():
|
def test_analyzer_has_definition() -> None:
|
||||||
a = analysis.CustomAnalyzer(
|
a = analysis.CustomAnalyzer(
|
||||||
"my_analyzer", tokenizer="keyword", filter=["lowercase"]
|
"my_analyzer", tokenizer="keyword", filter=["lowercase"]
|
||||||
)
|
)
|
||||||
@@ -48,7 +48,7 @@ def test_analyzer_has_definition():
|
|||||||
} == a.get_definition()
|
} == a.get_definition()
|
||||||
|
|
||||||
|
|
||||||
def test_simple_multiplexer_filter():
|
def test_simple_multiplexer_filter() -> None:
|
||||||
a = analysis.analyzer(
|
a = analysis.analyzer(
|
||||||
"my_analyzer",
|
"my_analyzer",
|
||||||
tokenizer="keyword",
|
tokenizer="keyword",
|
||||||
@@ -76,7 +76,7 @@ def test_simple_multiplexer_filter():
|
|||||||
} == a.get_analysis_definition()
|
} == a.get_analysis_definition()
|
||||||
|
|
||||||
|
|
||||||
def test_multiplexer_with_custom_filter():
|
def test_multiplexer_with_custom_filter() -> None:
|
||||||
a = analysis.analyzer(
|
a = analysis.analyzer(
|
||||||
"my_analyzer",
|
"my_analyzer",
|
||||||
tokenizer="keyword",
|
tokenizer="keyword",
|
||||||
@@ -107,7 +107,7 @@ def test_multiplexer_with_custom_filter():
|
|||||||
} == a.get_analysis_definition()
|
} == a.get_analysis_definition()
|
||||||
|
|
||||||
|
|
||||||
def test_conditional_token_filter():
|
def test_conditional_token_filter() -> None:
|
||||||
a = analysis.analyzer(
|
a = analysis.analyzer(
|
||||||
"my_cond",
|
"my_cond",
|
||||||
tokenizer=analysis.tokenizer("keyword"),
|
tokenizer=analysis.tokenizer("keyword"),
|
||||||
@@ -172,7 +172,7 @@ def test_normalizer_serializes_as_name() -> None:
|
|||||||
assert "my_normalizer" == n.to_dict()
|
assert "my_normalizer" == n.to_dict()
|
||||||
|
|
||||||
|
|
||||||
def test_normalizer_has_definition():
|
def test_normalizer_has_definition() -> None:
|
||||||
n = analysis.CustomNormalizer(
|
n = analysis.CustomNormalizer(
|
||||||
"my_normalizer", filter=["lowercase", "asciifolding"], char_filter=["quote"]
|
"my_normalizer", filter=["lowercase", "asciifolding"], char_filter=["quote"]
|
||||||
)
|
)
|
||||||
@@ -191,7 +191,7 @@ def test_tokenizer() -> None:
|
|||||||
assert {"type": "nGram", "min_gram": 3, "max_gram": 3} == t.get_definition()
|
assert {"type": "nGram", "min_gram": 3, "max_gram": 3} == t.get_definition()
|
||||||
|
|
||||||
|
|
||||||
def test_custom_analyzer_can_collect_custom_items():
|
def test_custom_analyzer_can_collect_custom_items() -> None:
|
||||||
trigram = analysis.tokenizer("trigram", "nGram", min_gram=3, max_gram=3)
|
trigram = analysis.tokenizer("trigram", "nGram", min_gram=3, max_gram=3)
|
||||||
my_stop = analysis.token_filter("my_stop", "stop", stopwords=["a", "b"])
|
my_stop = analysis.token_filter("my_stop", "stop", stopwords=["a", "b"])
|
||||||
umlauts = analysis.char_filter("umlauts", "pattern_replace", mappings=["ü=>ue"])
|
umlauts = analysis.char_filter("umlauts", "pattern_replace", mappings=["ü=>ue"])
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import ipaddress
|
|||||||
import pickle
|
import pickle
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from hashlib import sha256
|
from hashlib import sha256
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from pytest import raises
|
from pytest import raises
|
||||||
|
|
||||||
@@ -52,7 +53,7 @@ class MyDoc(document.Document):
|
|||||||
|
|
||||||
|
|
||||||
class MySubDoc(MyDoc):
|
class MySubDoc(MyDoc):
|
||||||
name = field.Keyword()
|
name: Any = field.Keyword()
|
||||||
|
|
||||||
class Index:
|
class Index:
|
||||||
name = "default-index"
|
name = "default-index"
|
||||||
@@ -92,10 +93,10 @@ class Secret(str):
|
|||||||
class SecretField(field.CustomField):
|
class SecretField(field.CustomField):
|
||||||
builtin_type = "text"
|
builtin_type = "text"
|
||||||
|
|
||||||
def _serialize(self, data):
|
def _serialize(self, data: Any) -> Any:
|
||||||
return codecs.encode(data, "rot_13")
|
return codecs.encode(data, "rot_13")
|
||||||
|
|
||||||
def _deserialize(self, data):
|
def _deserialize(self, data: Any) -> Any:
|
||||||
if isinstance(data, Secret):
|
if isinstance(data, Secret):
|
||||||
return data
|
return data
|
||||||
return Secret(codecs.decode(data, "rot_13"))
|
return Secret(codecs.decode(data, "rot_13"))
|
||||||
@@ -114,6 +115,8 @@ class NestedSecret(document.Document):
|
|||||||
class Index:
|
class Index:
|
||||||
name = "test-nested-secret"
|
name = "test-nested-secret"
|
||||||
|
|
||||||
|
_index: Any
|
||||||
|
|
||||||
|
|
||||||
class OptionalObjectWithRequiredField(document.Document):
|
class OptionalObjectWithRequiredField(document.Document):
|
||||||
comments = field.Nested(properties={"title": field.Keyword(required=True)})
|
comments = field.Nested(properties={"title": field.Keyword(required=True)})
|
||||||
@@ -121,6 +124,8 @@ class OptionalObjectWithRequiredField(document.Document):
|
|||||||
class Index:
|
class Index:
|
||||||
name = "test-required"
|
name = "test-required"
|
||||||
|
|
||||||
|
_index: Any
|
||||||
|
|
||||||
|
|
||||||
class Host(document.Document):
|
class Host(document.Document):
|
||||||
ip = field.Ip()
|
ip = field.Ip()
|
||||||
@@ -128,12 +133,14 @@ class Host(document.Document):
|
|||||||
class Index:
|
class Index:
|
||||||
name = "test-host"
|
name = "test-host"
|
||||||
|
|
||||||
|
_index: Any
|
||||||
|
|
||||||
|
|
||||||
def test_range_serializes_properly() -> None:
|
def test_range_serializes_properly() -> None:
|
||||||
class D(document.Document):
|
class D(document.Document):
|
||||||
lr = field.LongRange()
|
lr = field.LongRange()
|
||||||
|
|
||||||
d = D(lr=Range(lt=42))
|
d: Any = D(lr=Range(lt=42))
|
||||||
assert 40 in d.lr
|
assert 40 in d.lr
|
||||||
assert 47 not in d.lr
|
assert 47 not in d.lr
|
||||||
assert {"lr": {"lt": 42}} == d.to_dict()
|
assert {"lr": {"lt": 42}} == d.to_dict()
|
||||||
@@ -146,7 +153,7 @@ def test_range_deserializes_properly() -> None:
|
|||||||
class D(document.InnerDoc):
|
class D(document.InnerDoc):
|
||||||
lr = field.LongRange()
|
lr = field.LongRange()
|
||||||
|
|
||||||
d = D.from_opensearch({"lr": {"lt": 42}}, True)
|
d: Any = D.from_opensearch({"lr": {"lt": 42}}, True)
|
||||||
assert isinstance(d.lr, Range)
|
assert isinstance(d.lr, Range)
|
||||||
assert 40 in d.lr
|
assert 40 in d.lr
|
||||||
assert 47 not in d.lr
|
assert 47 not in d.lr
|
||||||
@@ -165,7 +172,7 @@ def test_conflicting_mapping_raises_error_in_index_to_dict() -> None:
|
|||||||
class B(document.Document):
|
class B(document.Document):
|
||||||
name = field.Keyword()
|
name = field.Keyword()
|
||||||
|
|
||||||
i = Index("i")
|
i: Any = Index("i")
|
||||||
i.document(A)
|
i.document(A)
|
||||||
i.document(B)
|
i.document(B)
|
||||||
|
|
||||||
@@ -174,7 +181,7 @@ def test_conflicting_mapping_raises_error_in_index_to_dict() -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_ip_address_serializes_properly() -> None:
|
def test_ip_address_serializes_properly() -> None:
|
||||||
host = Host(ip=ipaddress.IPv4Address("10.0.0.1"))
|
host: Any = Host(ip=ipaddress.IPv4Address("10.0.0.1"))
|
||||||
|
|
||||||
assert {"ip": "10.0.0.1"} == host.to_dict()
|
assert {"ip": "10.0.0.1"} == host.to_dict()
|
||||||
|
|
||||||
@@ -202,7 +209,7 @@ def test_matches_accepts_wildcards() -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_assigning_attrlist_to_field() -> None:
|
def test_assigning_attrlist_to_field() -> None:
|
||||||
sc = SimpleCommit()
|
sc: Any = SimpleCommit()
|
||||||
ls = ["README", "README.rst"]
|
ls = ["README", "README.rst"]
|
||||||
sc.files = utils.AttrList(ls)
|
sc.files = utils.AttrList(ls)
|
||||||
|
|
||||||
@@ -210,20 +217,20 @@ def test_assigning_attrlist_to_field() -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_optional_inner_objects_are_not_validated_if_missing() -> None:
|
def test_optional_inner_objects_are_not_validated_if_missing() -> None:
|
||||||
d = OptionalObjectWithRequiredField()
|
d: Any = OptionalObjectWithRequiredField()
|
||||||
|
|
||||||
assert d.full_clean() is None
|
assert d.full_clean() is None
|
||||||
|
|
||||||
|
|
||||||
def test_custom_field() -> None:
|
def test_custom_field() -> None:
|
||||||
s = SecretDoc(title=Secret("Hello"))
|
s1: Any = SecretDoc(title=Secret("Hello"))
|
||||||
|
|
||||||
assert {"title": "Uryyb"} == s.to_dict()
|
assert {"title": "Uryyb"} == s1.to_dict()
|
||||||
assert s.title == "Hello"
|
assert s1.title == "Hello"
|
||||||
|
|
||||||
s = SecretDoc.from_opensearch({"_source": {"title": "Uryyb"}})
|
s2: Any = SecretDoc.from_opensearch({"_source": {"title": "Uryyb"}})
|
||||||
assert s.title == "Hello"
|
assert s2.title == "Hello"
|
||||||
assert isinstance(s.title, Secret)
|
assert isinstance(s2.title, Secret)
|
||||||
|
|
||||||
|
|
||||||
def test_custom_field_mapping() -> None:
|
def test_custom_field_mapping() -> None:
|
||||||
@@ -233,7 +240,7 @@ def test_custom_field_mapping() -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_custom_field_in_nested() -> None:
|
def test_custom_field_in_nested() -> None:
|
||||||
s = NestedSecret()
|
s: Any = NestedSecret()
|
||||||
s.secrets.append(SecretDoc(title=Secret("Hello")))
|
s.secrets.append(SecretDoc(title=Secret("Hello")))
|
||||||
|
|
||||||
assert {"secrets": [{"title": "Uryyb"}]} == s.to_dict()
|
assert {"secrets": [{"title": "Uryyb"}]} == s.to_dict()
|
||||||
@@ -241,7 +248,7 @@ def test_custom_field_in_nested() -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_multi_works_after_doc_has_been_saved() -> None:
|
def test_multi_works_after_doc_has_been_saved() -> None:
|
||||||
c = SimpleCommit()
|
c: Any = SimpleCommit()
|
||||||
c.full_clean()
|
c.full_clean()
|
||||||
c.files.append("setup.py")
|
c.files.append("setup.py")
|
||||||
|
|
||||||
@@ -250,7 +257,7 @@ def test_multi_works_after_doc_has_been_saved() -> None:
|
|||||||
|
|
||||||
def test_multi_works_in_nested_after_doc_has_been_serialized() -> None:
|
def test_multi_works_in_nested_after_doc_has_been_serialized() -> None:
|
||||||
# Issue #359
|
# Issue #359
|
||||||
c = DocWithNested(comments=[Comment(title="First!")])
|
c: Any = DocWithNested(comments=[Comment(title="First!")])
|
||||||
|
|
||||||
assert [] == c.comments[0].tags
|
assert [] == c.comments[0].tags
|
||||||
assert {"comments": [{"title": "First!"}]} == c.to_dict()
|
assert {"comments": [{"title": "First!"}]} == c.to_dict()
|
||||||
@@ -258,17 +265,19 @@ def test_multi_works_in_nested_after_doc_has_been_serialized() -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_null_value_for_object() -> None:
|
def test_null_value_for_object() -> None:
|
||||||
d = MyDoc(inner=None)
|
d: Any = MyDoc(inner=None)
|
||||||
|
|
||||||
assert d.inner is None
|
assert d.inner is None
|
||||||
|
|
||||||
|
|
||||||
def test_inherited_doc_types_can_override_index():
|
def test_inherited_doc_types_can_override_index() -> None:
|
||||||
class MyDocDifferentIndex(MySubDoc):
|
class MyDocDifferentIndex(MySubDoc):
|
||||||
|
_index: Any
|
||||||
|
|
||||||
class Index:
|
class Index:
|
||||||
name = "not-default-index"
|
name = "not-default-index"
|
||||||
settings = {"number_of_replicas": 0}
|
settings = {"number_of_replicas": 0}
|
||||||
aliases = {"a": {}}
|
aliases: Any = {"a": {}}
|
||||||
analyzers = [analyzer("my_analizer", tokenizer="keyword")]
|
analyzers = [analyzer("my_analizer", tokenizer="keyword")]
|
||||||
|
|
||||||
assert MyDocDifferentIndex._index._name == "not-default-index"
|
assert MyDocDifferentIndex._index._name == "not-default-index"
|
||||||
@@ -295,8 +304,8 @@ def test_inherited_doc_types_can_override_index():
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_to_dict_with_meta():
|
def test_to_dict_with_meta() -> None:
|
||||||
d = MySubDoc(title="hello")
|
d: Any = MySubDoc(title="hello")
|
||||||
d.meta.routing = "some-parent"
|
d.meta.routing = "some-parent"
|
||||||
|
|
||||||
assert {
|
assert {
|
||||||
@@ -306,29 +315,29 @@ def test_to_dict_with_meta():
|
|||||||
} == d.to_dict(True)
|
} == d.to_dict(True)
|
||||||
|
|
||||||
|
|
||||||
def test_to_dict_with_meta_includes_custom_index():
|
def test_to_dict_with_meta_includes_custom_index() -> None:
|
||||||
d = MySubDoc(title="hello")
|
d: Any = MySubDoc(title="hello")
|
||||||
d.meta.index = "other-index"
|
d.meta.index = "other-index"
|
||||||
|
|
||||||
assert {"_index": "other-index", "_source": {"title": "hello"}} == d.to_dict(True)
|
assert {"_index": "other-index", "_source": {"title": "hello"}} == d.to_dict(True)
|
||||||
|
|
||||||
|
|
||||||
def test_to_dict_without_skip_empty_will_include_empty_fields() -> None:
|
def test_to_dict_without_skip_empty_will_include_empty_fields() -> None:
|
||||||
d = MySubDoc(tags=[], title=None, inner={})
|
d: Any = MySubDoc(tags=[], title=None, inner={})
|
||||||
|
|
||||||
assert {} == d.to_dict()
|
assert {} == d.to_dict()
|
||||||
assert {"tags": [], "title": None, "inner": {}} == d.to_dict(skip_empty=False)
|
assert {"tags": [], "title": None, "inner": {}} == d.to_dict(skip_empty=False)
|
||||||
|
|
||||||
|
|
||||||
def test_attribute_can_be_removed() -> None:
|
def test_attribute_can_be_removed() -> None:
|
||||||
d = MyDoc(title="hello")
|
d: Any = MyDoc(title="hello")
|
||||||
|
|
||||||
del d.title
|
del d.title
|
||||||
assert "title" not in d._d_
|
assert "title" not in d._d_
|
||||||
|
|
||||||
|
|
||||||
def test_doc_type_can_be_correctly_pickled() -> None:
|
def test_doc_type_can_be_correctly_pickled() -> None:
|
||||||
d = DocWithNested(
|
d: Any = DocWithNested(
|
||||||
title="Hello World!", comments=[Comment(title="hellp")], meta={"id": 42}
|
title="Hello World!", comments=[Comment(title="hellp")], meta={"id": 42}
|
||||||
)
|
)
|
||||||
s = pickle.dumps(d)
|
s = pickle.dumps(d)
|
||||||
@@ -343,14 +352,14 @@ def test_doc_type_can_be_correctly_pickled() -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_meta_is_accessible_even_on_empty_doc() -> None:
|
def test_meta_is_accessible_even_on_empty_doc() -> None:
|
||||||
d = MyDoc()
|
d1: Any = MyDoc()
|
||||||
d.meta
|
d1.meta
|
||||||
|
|
||||||
d = MyDoc(title="aaa")
|
d2: Any = MyDoc(title="aaa")
|
||||||
d.meta
|
d2.meta
|
||||||
|
|
||||||
|
|
||||||
def test_meta_field_mapping():
|
def test_meta_field_mapping() -> None:
|
||||||
class User(document.Document):
|
class User(document.Document):
|
||||||
username = field.Text()
|
username = field.Text()
|
||||||
|
|
||||||
@@ -373,7 +382,7 @@ def test_multi_value_fields() -> None:
|
|||||||
class Blog(document.Document):
|
class Blog(document.Document):
|
||||||
tags = field.Keyword(multi=True)
|
tags = field.Keyword(multi=True)
|
||||||
|
|
||||||
b = Blog()
|
b: Any = Blog()
|
||||||
assert [] == b.tags
|
assert [] == b.tags
|
||||||
b.tags.append("search")
|
b.tags.append("search")
|
||||||
b.tags.append("python")
|
b.tags.append("python")
|
||||||
@@ -382,20 +391,20 @@ def test_multi_value_fields() -> None:
|
|||||||
|
|
||||||
def test_docs_with_properties() -> None:
|
def test_docs_with_properties() -> None:
|
||||||
class User(document.Document):
|
class User(document.Document):
|
||||||
pwd_hash = field.Text()
|
pwd_hash: Any = field.Text()
|
||||||
|
|
||||||
def check_password(self, pwd):
|
def check_password(self, pwd: Any) -> Any:
|
||||||
return sha256(pwd).hexdigest() == self.pwd_hash
|
return sha256(pwd).hexdigest() == self.pwd_hash
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def password(self):
|
def password(self) -> Any:
|
||||||
raise AttributeError("readonly")
|
raise AttributeError("readonly")
|
||||||
|
|
||||||
@password.setter
|
@password.setter
|
||||||
def password(self, pwd):
|
def password(self, pwd: Any) -> None:
|
||||||
self.pwd_hash = sha256(pwd).hexdigest()
|
self.pwd_hash = sha256(pwd).hexdigest()
|
||||||
|
|
||||||
u = User(pwd_hash=sha256(b"secret").hexdigest())
|
u: Any = User(pwd_hash=sha256(b"secret").hexdigest())
|
||||||
assert u.check_password(b"secret")
|
assert u.check_password(b"secret")
|
||||||
assert not u.check_password(b"not-secret")
|
assert not u.check_password(b"not-secret")
|
||||||
|
|
||||||
@@ -409,8 +418,8 @@ def test_docs_with_properties() -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_nested_can_be_assigned_to() -> None:
|
def test_nested_can_be_assigned_to() -> None:
|
||||||
d1 = DocWithNested(comments=[Comment(title="First!")])
|
d1: Any = DocWithNested(comments=[Comment(title="First!")])
|
||||||
d2 = DocWithNested()
|
d2: Any = DocWithNested()
|
||||||
|
|
||||||
d2.comments = d1.comments
|
d2.comments = d1.comments
|
||||||
assert isinstance(d1.comments[0], Comment)
|
assert isinstance(d1.comments[0], Comment)
|
||||||
@@ -420,13 +429,13 @@ def test_nested_can_be_assigned_to() -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_nested_can_be_none() -> None:
|
def test_nested_can_be_none() -> None:
|
||||||
d = DocWithNested(comments=None, title="Hello World!")
|
d: Any = DocWithNested(comments=None, title="Hello World!")
|
||||||
|
|
||||||
assert {"title": "Hello World!"} == d.to_dict()
|
assert {"title": "Hello World!"} == d.to_dict()
|
||||||
|
|
||||||
|
|
||||||
def test_nested_defaults_to_list_and_can_be_updated() -> None:
|
def test_nested_defaults_to_list_and_can_be_updated() -> None:
|
||||||
md = DocWithNested()
|
md: Any = DocWithNested()
|
||||||
|
|
||||||
assert [] == md.comments
|
assert [] == md.comments
|
||||||
|
|
||||||
@@ -434,8 +443,8 @@ def test_nested_defaults_to_list_and_can_be_updated() -> None:
|
|||||||
assert {"comments": [{"title": "hello World!"}]} == md.to_dict()
|
assert {"comments": [{"title": "hello World!"}]} == md.to_dict()
|
||||||
|
|
||||||
|
|
||||||
def test_to_dict_is_recursive_and_can_cope_with_multi_values():
|
def test_to_dict_is_recursive_and_can_cope_with_multi_values() -> None:
|
||||||
md = MyDoc(name=["a", "b", "c"])
|
md: Any = MyDoc(name=["a", "b", "c"])
|
||||||
md.inner = [MyInner(old_field="of1"), MyInner(old_field="of2")]
|
md.inner = [MyInner(old_field="of1"), MyInner(old_field="of2")]
|
||||||
|
|
||||||
assert isinstance(md.inner[0], MyInner)
|
assert isinstance(md.inner[0], MyInner)
|
||||||
@@ -447,12 +456,12 @@ def test_to_dict_is_recursive_and_can_cope_with_multi_values():
|
|||||||
|
|
||||||
|
|
||||||
def test_to_dict_ignores_empty_collections() -> None:
|
def test_to_dict_ignores_empty_collections() -> None:
|
||||||
md = MySubDoc(name="", address={}, count=0, valid=False, tags=[])
|
md: Any = MySubDoc(name="", address={}, count=0, valid=False, tags=[])
|
||||||
|
|
||||||
assert {"name": "", "count": 0, "valid": False} == md.to_dict()
|
assert {"name": "", "count": 0, "valid": False} == md.to_dict()
|
||||||
|
|
||||||
|
|
||||||
def test_declarative_mapping_definition():
|
def test_declarative_mapping_definition() -> None:
|
||||||
assert issubclass(MyDoc, document.Document)
|
assert issubclass(MyDoc, document.Document)
|
||||||
assert hasattr(MyDoc, "_doc_type")
|
assert hasattr(MyDoc, "_doc_type")
|
||||||
assert {
|
assert {
|
||||||
@@ -465,7 +474,7 @@ def test_declarative_mapping_definition():
|
|||||||
} == MyDoc._doc_type.mapping.to_dict()
|
} == MyDoc._doc_type.mapping.to_dict()
|
||||||
|
|
||||||
|
|
||||||
def test_you_can_supply_own_mapping_instance():
|
def test_you_can_supply_own_mapping_instance() -> None:
|
||||||
class MyD(document.Document):
|
class MyD(document.Document):
|
||||||
title = field.Text()
|
title = field.Text()
|
||||||
|
|
||||||
@@ -479,9 +488,9 @@ def test_you_can_supply_own_mapping_instance():
|
|||||||
} == MyD._doc_type.mapping.to_dict()
|
} == MyD._doc_type.mapping.to_dict()
|
||||||
|
|
||||||
|
|
||||||
def test_document_can_be_created_dynamically():
|
def test_document_can_be_created_dynamically() -> None:
|
||||||
n = datetime.now()
|
n = datetime.now()
|
||||||
md = MyDoc(title="hello")
|
md: Any = MyDoc(title="hello")
|
||||||
md.name = "My Fancy Document!"
|
md.name = "My Fancy Document!"
|
||||||
md.created_at = n
|
md.created_at = n
|
||||||
|
|
||||||
@@ -501,13 +510,13 @@ def test_document_can_be_created_dynamically():
|
|||||||
|
|
||||||
|
|
||||||
def test_invalid_date_will_raise_exception() -> None:
|
def test_invalid_date_will_raise_exception() -> None:
|
||||||
md = MyDoc()
|
md: Any = MyDoc()
|
||||||
md.created_at = "not-a-date"
|
md.created_at = "not-a-date"
|
||||||
with raises(ValidationException):
|
with raises(ValidationException):
|
||||||
md.full_clean()
|
md.full_clean()
|
||||||
|
|
||||||
|
|
||||||
def test_document_inheritance():
|
def test_document_inheritance() -> None:
|
||||||
assert issubclass(MySubDoc, MyDoc)
|
assert issubclass(MySubDoc, MyDoc)
|
||||||
assert issubclass(MySubDoc, document.Document)
|
assert issubclass(MySubDoc, document.Document)
|
||||||
assert hasattr(MySubDoc, "_doc_type")
|
assert hasattr(MySubDoc, "_doc_type")
|
||||||
@@ -521,7 +530,7 @@ def test_document_inheritance():
|
|||||||
} == MySubDoc._doc_type.mapping.to_dict()
|
} == MySubDoc._doc_type.mapping.to_dict()
|
||||||
|
|
||||||
|
|
||||||
def test_child_class_can_override_parent():
|
def test_child_class_can_override_parent() -> None:
|
||||||
class A(document.Document):
|
class A(document.Document):
|
||||||
o = field.Object(dynamic=False, properties={"a": field.Text()})
|
o = field.Object(dynamic=False, properties={"a": field.Text()})
|
||||||
|
|
||||||
@@ -540,7 +549,7 @@ def test_child_class_can_override_parent():
|
|||||||
|
|
||||||
|
|
||||||
def test_meta_fields_are_stored_in_meta_and_ignored_by_to_dict() -> None:
|
def test_meta_fields_are_stored_in_meta_and_ignored_by_to_dict() -> None:
|
||||||
md = MySubDoc(meta={"id": 42}, name="My First doc!")
|
md: Any = MySubDoc(meta={"id": 42}, name="My First doc!")
|
||||||
|
|
||||||
md.meta.index = "my-index"
|
md.meta.index = "my-index"
|
||||||
assert md.meta.index == "my-index"
|
assert md.meta.index == "my-index"
|
||||||
@@ -549,7 +558,7 @@ def test_meta_fields_are_stored_in_meta_and_ignored_by_to_dict() -> None:
|
|||||||
assert {"id": 42, "index": "my-index"} == md.meta.to_dict()
|
assert {"id": 42, "index": "my-index"} == md.meta.to_dict()
|
||||||
|
|
||||||
|
|
||||||
def test_index_inheritance():
|
def test_index_inheritance() -> None:
|
||||||
assert issubclass(MyMultiSubDoc, MySubDoc)
|
assert issubclass(MyMultiSubDoc, MySubDoc)
|
||||||
assert issubclass(MyMultiSubDoc, MyDoc2)
|
assert issubclass(MyMultiSubDoc, MyDoc2)
|
||||||
assert issubclass(MyMultiSubDoc, document.Document)
|
assert issubclass(MyMultiSubDoc, document.Document)
|
||||||
@@ -568,31 +577,31 @@ def test_index_inheritance():
|
|||||||
|
|
||||||
def test_meta_fields_can_be_set_directly_in_init() -> None:
|
def test_meta_fields_can_be_set_directly_in_init() -> None:
|
||||||
p = object()
|
p = object()
|
||||||
md = MyDoc(_id=p, title="Hello World!")
|
md: Any = MyDoc(_id=p, title="Hello World!")
|
||||||
|
|
||||||
assert md.meta.id is p
|
assert md.meta.id is p
|
||||||
|
|
||||||
|
|
||||||
def test_save_no_index(mock_client) -> None:
|
def test_save_no_index(mock_client: Any) -> None:
|
||||||
md = MyDoc()
|
md: Any = MyDoc()
|
||||||
with raises(ValidationException):
|
with raises(ValidationException):
|
||||||
md.save(using="mock")
|
md.save(using="mock")
|
||||||
|
|
||||||
|
|
||||||
def test_delete_no_index(mock_client) -> None:
|
def test_delete_no_index(mock_client: Any) -> None:
|
||||||
md = MyDoc()
|
md: Any = MyDoc()
|
||||||
with raises(ValidationException):
|
with raises(ValidationException):
|
||||||
md.delete(using="mock")
|
md.delete(using="mock")
|
||||||
|
|
||||||
|
|
||||||
def test_update_no_fields() -> None:
|
def test_update_no_fields() -> None:
|
||||||
md = MyDoc()
|
md: Any = MyDoc()
|
||||||
with raises(IllegalOperation):
|
with raises(IllegalOperation):
|
||||||
md.update()
|
md.update()
|
||||||
|
|
||||||
|
|
||||||
def test_search_with_custom_alias_and_index(mock_client) -> None:
|
def test_search_with_custom_alias_and_index(mock_client: Any) -> None:
|
||||||
search_object = MyDoc.search(
|
search_object: Any = MyDoc.search(
|
||||||
using="staging", index=["custom_index1", "custom_index2"]
|
using="staging", index=["custom_index1", "custom_index2"]
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -600,7 +609,7 @@ def test_search_with_custom_alias_and_index(mock_client) -> None:
|
|||||||
assert search_object._index == ["custom_index1", "custom_index2"]
|
assert search_object._index == ["custom_index1", "custom_index2"]
|
||||||
|
|
||||||
|
|
||||||
def test_from_opensearch_respects_underscored_non_meta_fields():
|
def test_from_opensearch_respects_underscored_non_meta_fields() -> None:
|
||||||
doc = {
|
doc = {
|
||||||
"_index": "test-index",
|
"_index": "test-index",
|
||||||
"_id": "opensearch",
|
"_id": "opensearch",
|
||||||
@@ -617,18 +626,18 @@ def test_from_opensearch_respects_underscored_non_meta_fields():
|
|||||||
class Index:
|
class Index:
|
||||||
name = "test-company"
|
name = "test-company"
|
||||||
|
|
||||||
c = Company.from_opensearch(doc)
|
c: Any = Company.from_opensearch(doc)
|
||||||
|
|
||||||
assert c.meta.fields._tags == ["search"]
|
assert c.meta.fields._tags == ["search"]
|
||||||
assert c.meta.fields._routing == "opensearch"
|
assert c.meta.fields._routing == "opensearch"
|
||||||
assert c._tagline == "You know, for search"
|
assert c._tagline == "You know, for search"
|
||||||
|
|
||||||
|
|
||||||
def test_nested_and_object_inner_doc():
|
def test_nested_and_object_inner_doc() -> None:
|
||||||
class MySubDocWithNested(MyDoc):
|
class MySubDocWithNested(MyDoc):
|
||||||
nested_inner = field.Nested(MyInner)
|
nested_inner = field.Nested(MyInner)
|
||||||
|
|
||||||
props = MySubDocWithNested._doc_type.mapping.to_dict()["properties"]
|
props: Any = MySubDocWithNested._doc_type.mapping.to_dict()["properties"]
|
||||||
assert props == {
|
assert props == {
|
||||||
"created_at": {"type": "date"},
|
"created_at": {"type": "date"},
|
||||||
"inner": {"properties": {"old_field": {"type": "text"}}, "type": "object"},
|
"inner": {"properties": {"old_field": {"type": "text"}}, "type": "object"},
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@@ -72,7 +73,7 @@ def test_query_is_created_properly() -> None:
|
|||||||
} == s.to_dict()
|
} == s.to_dict()
|
||||||
|
|
||||||
|
|
||||||
def test_query_is_created_properly_with_sort_tuple():
|
def test_query_is_created_properly_with_sort_tuple() -> None:
|
||||||
bs = BlogSearch("python search", sort=("category", "-title"))
|
bs = BlogSearch("python search", sort=("category", "-title"))
|
||||||
s = bs.build_search()
|
s = bs.build_search()
|
||||||
|
|
||||||
@@ -96,7 +97,7 @@ def test_query_is_created_properly_with_sort_tuple():
|
|||||||
} == s.to_dict()
|
} == s.to_dict()
|
||||||
|
|
||||||
|
|
||||||
def test_filter_is_applied_to_search_but_not_relevant_facet():
|
def test_filter_is_applied_to_search_but_not_relevant_facet() -> None:
|
||||||
bs = BlogSearch("python search", filters={"category": "opensearch"})
|
bs = BlogSearch("python search", filters={"category": "opensearch"})
|
||||||
s = bs.build_search()
|
s = bs.build_search()
|
||||||
|
|
||||||
@@ -119,7 +120,7 @@ def test_filter_is_applied_to_search_but_not_relevant_facet():
|
|||||||
} == s.to_dict()
|
} == s.to_dict()
|
||||||
|
|
||||||
|
|
||||||
def test_filters_are_applied_to_search_ant_relevant_facets():
|
def test_filters_are_applied_to_search_ant_relevant_facets() -> None:
|
||||||
bs = BlogSearch(
|
bs = BlogSearch(
|
||||||
"python search",
|
"python search",
|
||||||
filters={"category": "opensearch", "tags": ["python", "django"]},
|
filters={"category": "opensearch", "tags": ["python", "django"]},
|
||||||
@@ -159,7 +160,7 @@ def test_date_histogram_facet_with_1970_01_01_date() -> None:
|
|||||||
assert dhf.get_value({"key": 0}) == datetime(1970, 1, 1, 0, 0)
|
assert dhf.get_value({"key": 0}) == datetime(1970, 1, 1, 0, 0)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize( # type: ignore
|
||||||
["interval_type", "interval"],
|
["interval_type", "interval"],
|
||||||
[
|
[
|
||||||
("interval", "year"),
|
("interval", "year"),
|
||||||
@@ -186,7 +187,7 @@ def test_date_histogram_facet_with_1970_01_01_date() -> None:
|
|||||||
("fixed_interval", "1h"),
|
("fixed_interval", "1h"),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_date_histogram_interval_types(interval_type, interval) -> None:
|
def test_date_histogram_interval_types(interval_type: Any, interval: Any) -> None:
|
||||||
dhf = DateHistogramFacet(field="@timestamp", **{interval_type: interval})
|
dhf = DateHistogramFacet(field="@timestamp", **{interval_type: interval})
|
||||||
assert dhf.get_aggregation().to_dict() == {
|
assert dhf.get_aggregation().to_dict() == {
|
||||||
"date_histogram": {
|
"date_histogram": {
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
import base64
|
import base64
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from ipaddress import ip_address
|
from ipaddress import ip_address
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from dateutil import tz
|
from dateutil import tz
|
||||||
@@ -59,7 +60,7 @@ def test_boolean_deserialization() -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_date_field_can_have_default_tz() -> None:
|
def test_date_field_can_have_default_tz() -> None:
|
||||||
f = field.Date(default_timezone="UTC")
|
f: Any = field.Date(default_timezone="UTC")
|
||||||
now = datetime.now()
|
now = datetime.now()
|
||||||
|
|
||||||
now_with_tz = f._deserialize(now)
|
now_with_tz = f._deserialize(now)
|
||||||
@@ -76,7 +77,7 @@ def test_date_field_can_have_default_tz() -> None:
|
|||||||
def test_custom_field_car_wrap_other_field() -> None:
|
def test_custom_field_car_wrap_other_field() -> None:
|
||||||
class MyField(field.CustomField):
|
class MyField(field.CustomField):
|
||||||
@property
|
@property
|
||||||
def builtin_type(self):
|
def builtin_type(self) -> Any:
|
||||||
return field.Text(**self._params)
|
return field.Text(**self._params)
|
||||||
|
|
||||||
assert {"type": "text", "index": "not_analyzed"} == MyField(
|
assert {"type": "text", "index": "not_analyzed"} == MyField(
|
||||||
@@ -91,7 +92,7 @@ def test_field_from_dict() -> None:
|
|||||||
assert {"type": "text", "index": "not_analyzed"} == f.to_dict()
|
assert {"type": "text", "index": "not_analyzed"} == f.to_dict()
|
||||||
|
|
||||||
|
|
||||||
def test_multi_fields_are_accepted_and_parsed():
|
def test_multi_fields_are_accepted_and_parsed() -> None:
|
||||||
f = field.construct_field(
|
f = field.construct_field(
|
||||||
"text",
|
"text",
|
||||||
fields={"raw": {"type": "keyword"}, "eng": field.Text(analyzer="english")},
|
fields={"raw": {"type": "keyword"}, "eng": field.Text(analyzer="english")},
|
||||||
@@ -123,7 +124,7 @@ def test_field_supports_multiple_analyzers() -> None:
|
|||||||
} == f.to_dict()
|
} == f.to_dict()
|
||||||
|
|
||||||
|
|
||||||
def test_multifield_supports_multiple_analyzers():
|
def test_multifield_supports_multiple_analyzers() -> None:
|
||||||
f = field.Text(
|
f = field.Text(
|
||||||
fields={
|
fields={
|
||||||
"f1": field.Text(search_analyzer="keyword", analyzer="snowball"),
|
"f1": field.Text(search_analyzer="keyword", analyzer="snowball"),
|
||||||
@@ -145,8 +146,8 @@ def test_multifield_supports_multiple_analyzers():
|
|||||||
|
|
||||||
def test_scaled_float() -> None:
|
def test_scaled_float() -> None:
|
||||||
with pytest.raises(TypeError):
|
with pytest.raises(TypeError):
|
||||||
field.ScaledFloat()
|
field.ScaledFloat() # type: ignore
|
||||||
f = field.ScaledFloat(123)
|
f: Any = field.ScaledFloat(scaling_factor=123)
|
||||||
assert f.to_dict() == {"scaling_factor": 123, "type": "scaled_float"}
|
assert f.to_dict() == {"scaling_factor": 123, "type": "scaled_float"}
|
||||||
|
|
||||||
|
|
||||||
@@ -204,7 +205,7 @@ def test_object_disabled() -> None:
|
|||||||
assert f.to_dict() == {"type": "object", "enabled": False}
|
assert f.to_dict() == {"type": "object", "enabled": False}
|
||||||
|
|
||||||
|
|
||||||
def test_object_constructor():
|
def test_object_constructor() -> None:
|
||||||
expected = {"type": "object", "properties": {"inner_int": {"type": "integer"}}}
|
expected = {"type": "object", "properties": {"inner_int": {"type": "integer"}}}
|
||||||
|
|
||||||
class Inner(InnerDoc):
|
class Inner(InnerDoc):
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
import string
|
import string
|
||||||
from random import choice
|
from random import choice
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from pytest import raises
|
from pytest import raises
|
||||||
|
|
||||||
@@ -65,7 +66,7 @@ def test_search_is_limited_to_index_name() -> None:
|
|||||||
|
|
||||||
def test_cloned_index_has_copied_settings_and_using() -> None:
|
def test_cloned_index_has_copied_settings_and_using() -> None:
|
||||||
client = object()
|
client = object()
|
||||||
i = Index("my-index", using=client)
|
i: Any = Index("my-index", using=client)
|
||||||
i.settings(number_of_shards=1)
|
i.settings(number_of_shards=1)
|
||||||
|
|
||||||
i2 = i.clone("my-other-index")
|
i2 = i.clone("my-other-index")
|
||||||
@@ -82,7 +83,7 @@ def test_cloned_index_has_analysis_attribute() -> None:
|
|||||||
over the `_analysis` attribute.
|
over the `_analysis` attribute.
|
||||||
"""
|
"""
|
||||||
client = object()
|
client = object()
|
||||||
i = Index("my-index", using=client)
|
i: Any = Index("my-index", using=client)
|
||||||
|
|
||||||
random_analyzer_name = "".join((choice(string.ascii_letters) for _ in range(100)))
|
random_analyzer_name = "".join((choice(string.ascii_letters) for _ in range(100)))
|
||||||
random_analyzer = analyzer(
|
random_analyzer = analyzer(
|
||||||
@@ -97,7 +98,7 @@ def test_cloned_index_has_analysis_attribute() -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_settings_are_saved() -> None:
|
def test_settings_are_saved() -> None:
|
||||||
i = Index("i")
|
i: Any = Index("i")
|
||||||
i.settings(number_of_replicas=0)
|
i.settings(number_of_replicas=0)
|
||||||
i.settings(number_of_shards=1)
|
i.settings(number_of_shards=1)
|
||||||
|
|
||||||
@@ -105,7 +106,7 @@ def test_settings_are_saved() -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_registered_doc_type_included_in_to_dict() -> None:
|
def test_registered_doc_type_included_in_to_dict() -> None:
|
||||||
i = Index("i", using="alias")
|
i: Any = Index("i", using="alias")
|
||||||
i.document(Post)
|
i.document(Post)
|
||||||
|
|
||||||
assert {
|
assert {
|
||||||
@@ -119,7 +120,7 @@ def test_registered_doc_type_included_in_to_dict() -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_registered_doc_type_included_in_search() -> None:
|
def test_registered_doc_type_included_in_search() -> None:
|
||||||
i = Index("i", using="alias")
|
i: Any = Index("i", using="alias")
|
||||||
i.document(Post)
|
i.document(Post)
|
||||||
|
|
||||||
s = i.search()
|
s = i.search()
|
||||||
@@ -129,9 +130,9 @@ def test_registered_doc_type_included_in_search() -> None:
|
|||||||
|
|
||||||
def test_aliases_add_to_object() -> None:
|
def test_aliases_add_to_object() -> None:
|
||||||
random_alias = "".join((choice(string.ascii_letters) for _ in range(100)))
|
random_alias = "".join((choice(string.ascii_letters) for _ in range(100)))
|
||||||
alias_dict = {random_alias: {}}
|
alias_dict: Any = {random_alias: {}}
|
||||||
|
|
||||||
index = Index("i", using="alias")
|
index: Any = Index("i", using="alias")
|
||||||
index.aliases(**alias_dict)
|
index.aliases(**alias_dict)
|
||||||
|
|
||||||
assert index._aliases == alias_dict
|
assert index._aliases == alias_dict
|
||||||
@@ -139,21 +140,21 @@ def test_aliases_add_to_object() -> None:
|
|||||||
|
|
||||||
def test_aliases_returned_from_to_dict() -> None:
|
def test_aliases_returned_from_to_dict() -> None:
|
||||||
random_alias = "".join((choice(string.ascii_letters) for _ in range(100)))
|
random_alias = "".join((choice(string.ascii_letters) for _ in range(100)))
|
||||||
alias_dict = {random_alias: {}}
|
alias_dict: Any = {random_alias: {}}
|
||||||
|
|
||||||
index = Index("i", using="alias")
|
index: Any = Index("i", using="alias")
|
||||||
index.aliases(**alias_dict)
|
index.aliases(**alias_dict)
|
||||||
|
|
||||||
assert index._aliases == index.to_dict()["aliases"] == alias_dict
|
assert index._aliases == index.to_dict()["aliases"] == alias_dict
|
||||||
|
|
||||||
|
|
||||||
def test_analyzers_added_to_object():
|
def test_analyzers_added_to_object() -> None:
|
||||||
random_analyzer_name = "".join((choice(string.ascii_letters) for _ in range(100)))
|
random_analyzer_name = "".join((choice(string.ascii_letters) for _ in range(100)))
|
||||||
random_analyzer = analyzer(
|
random_analyzer = analyzer(
|
||||||
random_analyzer_name, tokenizer="standard", filter="standard"
|
random_analyzer_name, tokenizer="standard", filter="standard"
|
||||||
)
|
)
|
||||||
|
|
||||||
index = Index("i", using="alias")
|
index: Any = Index("i", using="alias")
|
||||||
index.analyzer(random_analyzer)
|
index.analyzer(random_analyzer)
|
||||||
|
|
||||||
assert index._analysis["analyzer"][random_analyzer_name] == {
|
assert index._analysis["analyzer"][random_analyzer_name] == {
|
||||||
@@ -163,12 +164,12 @@ def test_analyzers_added_to_object():
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_analyzers_returned_from_to_dict():
|
def test_analyzers_returned_from_to_dict() -> None:
|
||||||
random_analyzer_name = "".join((choice(string.ascii_letters) for _ in range(100)))
|
random_analyzer_name = "".join((choice(string.ascii_letters) for _ in range(100)))
|
||||||
random_analyzer = analyzer(
|
random_analyzer = analyzer(
|
||||||
random_analyzer_name, tokenizer="standard", filter="standard"
|
random_analyzer_name, tokenizer="standard", filter="standard"
|
||||||
)
|
)
|
||||||
index = Index("i", using="alias")
|
index: Any = Index("i", using="alias")
|
||||||
index.analyzer(random_analyzer)
|
index.analyzer(random_analyzer)
|
||||||
|
|
||||||
assert index.to_dict()["settings"]["analysis"]["analyzer"][
|
assert index.to_dict()["settings"]["analysis"]["analyzer"][
|
||||||
@@ -177,21 +178,21 @@ def test_analyzers_returned_from_to_dict():
|
|||||||
|
|
||||||
|
|
||||||
def test_conflicting_analyzer_raises_error() -> None:
|
def test_conflicting_analyzer_raises_error() -> None:
|
||||||
i = Index("i")
|
i: Any = Index("i")
|
||||||
i.analyzer("my_analyzer", tokenizer="whitespace", filter=["lowercase", "stop"])
|
i.analyzer("my_analyzer", tokenizer="whitespace", filter=["lowercase", "stop"])
|
||||||
|
|
||||||
with raises(ValueError):
|
with raises(ValueError):
|
||||||
i.analyzer("my_analyzer", tokenizer="keyword", filter=["lowercase", "stop"])
|
i.analyzer("my_analyzer", tokenizer="keyword", filter=["lowercase", "stop"])
|
||||||
|
|
||||||
|
|
||||||
def test_index_template_can_have_order():
|
def test_index_template_can_have_order() -> None:
|
||||||
i = Index("i-*")
|
i: Any = Index("i-*")
|
||||||
it = i.as_template("i", order=2)
|
it = i.as_template("i", order=2)
|
||||||
|
|
||||||
assert {"index_patterns": ["i-*"], "order": 2} == it.to_dict()
|
assert {"index_patterns": ["i-*"], "order": 2} == it.to_dict()
|
||||||
|
|
||||||
|
|
||||||
def test_index_template_save_result(mock_client) -> None:
|
def test_index_template_save_result(mock_client: Any) -> None:
|
||||||
it = IndexTemplate("test-template", "test-*")
|
it: Any = IndexTemplate("test-template", "test-*")
|
||||||
|
|
||||||
assert it.save(using="mock") == mock_client.indices.put_template()
|
assert it.save(using="mock") == mock_client.indices.put_template()
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ def test_mapping_can_has_fields() -> None:
|
|||||||
} == m.to_dict()
|
} == m.to_dict()
|
||||||
|
|
||||||
|
|
||||||
def test_mapping_update_is_recursive():
|
def test_mapping_update_is_recursive() -> None:
|
||||||
m1 = mapping.Mapping()
|
m1 = mapping.Mapping()
|
||||||
m1.field("title", "text")
|
m1.field("title", "text")
|
||||||
m1.field("author", "object")
|
m1.field("author", "object")
|
||||||
@@ -83,7 +83,7 @@ def test_properties_can_iterate_over_all_the_fields() -> None:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_mapping_can_collect_all_analyzers_and_normalizers():
|
def test_mapping_can_collect_all_analyzers_and_normalizers() -> None:
|
||||||
a1 = analysis.analyzer(
|
a1 = analysis.analyzer(
|
||||||
"my_analyzer1",
|
"my_analyzer1",
|
||||||
tokenizer="keyword",
|
tokenizer="keyword",
|
||||||
@@ -156,7 +156,7 @@ def test_mapping_can_collect_all_analyzers_and_normalizers():
|
|||||||
assert json.loads(json.dumps(m.to_dict())) == m.to_dict()
|
assert json.loads(json.dumps(m.to_dict())) == m.to_dict()
|
||||||
|
|
||||||
|
|
||||||
def test_mapping_can_collect_multiple_analyzers():
|
def test_mapping_can_collect_multiple_analyzers() -> None:
|
||||||
a1 = analysis.analyzer(
|
a1 = analysis.analyzer(
|
||||||
"my_analyzer1",
|
"my_analyzer1",
|
||||||
tokenizer="keyword",
|
tokenizer="keyword",
|
||||||
|
|||||||
@@ -25,6 +25,8 @@
|
|||||||
# specific language governing permissions and limitations
|
# specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from pytest import raises
|
from pytest import raises
|
||||||
|
|
||||||
from opensearchpy.helpers import function, query
|
from opensearchpy.helpers import function, query
|
||||||
@@ -122,8 +124,8 @@ def test_other_and_bool_appends_other_to_must() -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_bool_and_other_appends_other_to_must() -> None:
|
def test_bool_and_other_appends_other_to_must() -> None:
|
||||||
q1 = query.Match(f="value1")
|
q1: Any = query.Match(f="value1")
|
||||||
qb = query.Bool()
|
qb: Any = query.Bool()
|
||||||
|
|
||||||
q = qb & q1
|
q = qb & q1
|
||||||
assert q is not qb
|
assert q is not qb
|
||||||
@@ -463,7 +465,7 @@ def test_function_score_with_functions() -> None:
|
|||||||
} == q.to_dict()
|
} == q.to_dict()
|
||||||
|
|
||||||
|
|
||||||
def test_function_score_with_no_function_is_boost_factor():
|
def test_function_score_with_no_function_is_boost_factor() -> None:
|
||||||
q = query.Q(
|
q = query.Q(
|
||||||
"function_score",
|
"function_score",
|
||||||
functions=[query.SF({"weight": 20, "filter": query.Q("term", f=42)})],
|
functions=[query.SF({"weight": 20, "filter": query.Q("term", f=42)})],
|
||||||
@@ -474,7 +476,7 @@ def test_function_score_with_no_function_is_boost_factor():
|
|||||||
} == q.to_dict()
|
} == q.to_dict()
|
||||||
|
|
||||||
|
|
||||||
def test_function_score_to_dict():
|
def test_function_score_to_dict() -> None:
|
||||||
q = query.Q(
|
q = query.Q(
|
||||||
"function_score",
|
"function_score",
|
||||||
query=query.Q("match", title="python"),
|
query=query.Q("match", title="python"),
|
||||||
@@ -503,7 +505,7 @@ def test_function_score_to_dict():
|
|||||||
assert d == q.to_dict()
|
assert d == q.to_dict()
|
||||||
|
|
||||||
|
|
||||||
def test_function_score_with_single_function():
|
def test_function_score_with_single_function() -> None:
|
||||||
d = {
|
d = {
|
||||||
"function_score": {
|
"function_score": {
|
||||||
"filter": {"term": {"tags": "python"}},
|
"filter": {"term": {"tags": "python"}},
|
||||||
@@ -521,7 +523,7 @@ def test_function_score_with_single_function():
|
|||||||
assert "doc['comment_count'] * _score" == sf.script
|
assert "doc['comment_count'] * _score" == sf.script
|
||||||
|
|
||||||
|
|
||||||
def test_function_score_from_dict():
|
def test_function_score_from_dict() -> None:
|
||||||
d = {
|
d = {
|
||||||
"function_score": {
|
"function_score": {
|
||||||
"filter": {"term": {"tags": "python"}},
|
"filter": {"term": {"tags": "python"}},
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
import pickle
|
import pickle
|
||||||
from datetime import date
|
from datetime import date
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from pytest import fixture, raises
|
from pytest import fixture, raises
|
||||||
|
|
||||||
@@ -36,12 +37,12 @@ from opensearchpy.helpers.aggs import Terms
|
|||||||
from opensearchpy.helpers.response.aggs import AggResponse, Bucket, BucketData
|
from opensearchpy.helpers.response.aggs import AggResponse, Bucket, BucketData
|
||||||
|
|
||||||
|
|
||||||
@fixture
|
@fixture # type: ignore
|
||||||
def agg_response(aggs_search, aggs_data):
|
def agg_response(aggs_search: Any, aggs_data: Any) -> Any:
|
||||||
return response.Response(aggs_search, aggs_data)
|
return response.Response(aggs_search, aggs_data)
|
||||||
|
|
||||||
|
|
||||||
def test_agg_response_is_pickleable(agg_response) -> None:
|
def test_agg_response_is_pickleable(agg_response: Any) -> None:
|
||||||
agg_response.hits
|
agg_response.hits
|
||||||
r = pickle.loads(pickle.dumps(agg_response))
|
r = pickle.loads(pickle.dumps(agg_response))
|
||||||
|
|
||||||
@@ -50,7 +51,7 @@ def test_agg_response_is_pickleable(agg_response) -> None:
|
|||||||
assert r.hits == agg_response.hits
|
assert r.hits == agg_response.hits
|
||||||
|
|
||||||
|
|
||||||
def test_response_is_pickleable(dummy_response) -> None:
|
def test_response_is_pickleable(dummy_response: Any) -> None:
|
||||||
res = response.Response(Search(), dummy_response)
|
res = response.Response(Search(), dummy_response)
|
||||||
res.hits
|
res.hits
|
||||||
r = pickle.loads(pickle.dumps(res))
|
r = pickle.loads(pickle.dumps(res))
|
||||||
@@ -60,7 +61,7 @@ def test_response_is_pickleable(dummy_response) -> None:
|
|||||||
assert r.hits == res.hits
|
assert r.hits == res.hits
|
||||||
|
|
||||||
|
|
||||||
def test_hit_is_pickleable(dummy_response) -> None:
|
def test_hit_is_pickleable(dummy_response: Any) -> None:
|
||||||
res = response.Response(Search(), dummy_response)
|
res = response.Response(Search(), dummy_response)
|
||||||
hits = pickle.loads(pickle.dumps(res.hits))
|
hits = pickle.loads(pickle.dumps(res.hits))
|
||||||
|
|
||||||
@@ -68,14 +69,14 @@ def test_hit_is_pickleable(dummy_response) -> None:
|
|||||||
assert hits[0].meta == res.hits[0].meta
|
assert hits[0].meta == res.hits[0].meta
|
||||||
|
|
||||||
|
|
||||||
def test_response_stores_search(dummy_response) -> None:
|
def test_response_stores_search(dummy_response: Any) -> None:
|
||||||
s = Search()
|
s = Search()
|
||||||
r = response.Response(s, dummy_response)
|
r = response.Response(s, dummy_response)
|
||||||
|
|
||||||
assert r._search is s
|
assert r._search is s
|
||||||
|
|
||||||
|
|
||||||
def test_interactive_helpers(dummy_response) -> None:
|
def test_interactive_helpers(dummy_response: Any) -> None:
|
||||||
res = response.Response(Search(), dummy_response)
|
res = response.Response(Search(), dummy_response)
|
||||||
hits = res.hits
|
hits = res.hits
|
||||||
h = hits[0]
|
h = hits[0]
|
||||||
@@ -98,19 +99,19 @@ def test_interactive_helpers(dummy_response) -> None:
|
|||||||
] == repr(h)
|
] == repr(h)
|
||||||
|
|
||||||
|
|
||||||
def test_empty_response_is_false(dummy_response) -> None:
|
def test_empty_response_is_false(dummy_response: Any) -> None:
|
||||||
dummy_response["hits"]["hits"] = []
|
dummy_response["hits"]["hits"] = []
|
||||||
res = response.Response(Search(), dummy_response)
|
res = response.Response(Search(), dummy_response)
|
||||||
|
|
||||||
assert not res
|
assert not res
|
||||||
|
|
||||||
|
|
||||||
def test_len_response(dummy_response) -> None:
|
def test_len_response(dummy_response: Any) -> None:
|
||||||
res = response.Response(Search(), dummy_response)
|
res = response.Response(Search(), dummy_response)
|
||||||
assert len(res) == 4
|
assert len(res) == 4
|
||||||
|
|
||||||
|
|
||||||
def test_iterating_over_response_gives_you_hits(dummy_response) -> None:
|
def test_iterating_over_response_gives_you_hits(dummy_response: Any) -> None:
|
||||||
res = response.Response(Search(), dummy_response)
|
res = response.Response(Search(), dummy_response)
|
||||||
hits = list(h for h in res)
|
hits = list(h for h in res)
|
||||||
|
|
||||||
@@ -127,7 +128,7 @@ def test_iterating_over_response_gives_you_hits(dummy_response) -> None:
|
|||||||
assert hits[1].meta.routing == "opensearch"
|
assert hits[1].meta.routing == "opensearch"
|
||||||
|
|
||||||
|
|
||||||
def test_hits_get_wrapped_to_contain_additional_attrs(dummy_response) -> None:
|
def test_hits_get_wrapped_to_contain_additional_attrs(dummy_response: Any) -> None:
|
||||||
res = response.Response(Search(), dummy_response)
|
res = response.Response(Search(), dummy_response)
|
||||||
hits = res.hits
|
hits = res.hits
|
||||||
|
|
||||||
@@ -135,7 +136,7 @@ def test_hits_get_wrapped_to_contain_additional_attrs(dummy_response) -> None:
|
|||||||
assert 12.0 == hits.max_score
|
assert 12.0 == hits.max_score
|
||||||
|
|
||||||
|
|
||||||
def test_hits_provide_dot_and_bracket_access_to_attrs(dummy_response) -> None:
|
def test_hits_provide_dot_and_bracket_access_to_attrs(dummy_response: Any) -> None:
|
||||||
res = response.Response(Search(), dummy_response)
|
res = response.Response(Search(), dummy_response)
|
||||||
h = res.hits[0]
|
h = res.hits[0]
|
||||||
|
|
||||||
@@ -151,30 +152,32 @@ def test_hits_provide_dot_and_bracket_access_to_attrs(dummy_response) -> None:
|
|||||||
h.not_there
|
h.not_there
|
||||||
|
|
||||||
|
|
||||||
def test_slicing_on_response_slices_on_hits(dummy_response) -> None:
|
def test_slicing_on_response_slices_on_hits(dummy_response: Any) -> None:
|
||||||
res = response.Response(Search(), dummy_response)
|
res = response.Response(Search(), dummy_response)
|
||||||
|
|
||||||
assert res[0] is res.hits[0]
|
assert res[0] is res.hits[0]
|
||||||
assert res[::-1] == res.hits[::-1]
|
assert res[::-1] == res.hits[::-1]
|
||||||
|
|
||||||
|
|
||||||
def test_aggregation_base(agg_response) -> None:
|
def test_aggregation_base(agg_response: Any) -> None:
|
||||||
assert agg_response.aggs is agg_response.aggregations
|
assert agg_response.aggs is agg_response.aggregations
|
||||||
assert isinstance(agg_response.aggs, response.AggResponse)
|
assert isinstance(agg_response.aggs, response.AggResponse)
|
||||||
|
|
||||||
|
|
||||||
def test_metric_agg_works(agg_response) -> None:
|
def test_metric_agg_works(agg_response: Any) -> None:
|
||||||
assert 25052.0 == agg_response.aggs.sum_lines.value
|
assert 25052.0 == agg_response.aggs.sum_lines.value
|
||||||
|
|
||||||
|
|
||||||
def test_aggregations_can_be_iterated_over(agg_response) -> None:
|
def test_aggregations_can_be_iterated_over(agg_response: Any) -> None:
|
||||||
aggs = [a for a in agg_response.aggs]
|
aggs = [a for a in agg_response.aggs]
|
||||||
|
|
||||||
assert len(aggs) == 3
|
assert len(aggs) == 3
|
||||||
assert all(map(lambda a: isinstance(a, AggResponse), aggs))
|
assert all(map(lambda a: isinstance(a, AggResponse), aggs))
|
||||||
|
|
||||||
|
|
||||||
def test_aggregations_can_be_retrieved_by_name(agg_response, aggs_search) -> None:
|
def test_aggregations_can_be_retrieved_by_name(
|
||||||
|
agg_response: Any, aggs_search: Any
|
||||||
|
) -> None:
|
||||||
a = agg_response.aggs["popular_files"]
|
a = agg_response.aggs["popular_files"]
|
||||||
|
|
||||||
assert isinstance(a, BucketData)
|
assert isinstance(a, BucketData)
|
||||||
@@ -182,7 +185,7 @@ def test_aggregations_can_be_retrieved_by_name(agg_response, aggs_search) -> Non
|
|||||||
assert a._meta["aggs"] is aggs_search.aggs.aggs["popular_files"]
|
assert a._meta["aggs"] is aggs_search.aggs.aggs["popular_files"]
|
||||||
|
|
||||||
|
|
||||||
def test_bucket_response_can_be_iterated_over(agg_response) -> None:
|
def test_bucket_response_can_be_iterated_over(agg_response: Any) -> None:
|
||||||
popular_files = agg_response.aggregations.popular_files
|
popular_files = agg_response.aggregations.popular_files
|
||||||
|
|
||||||
buckets = [b for b in popular_files]
|
buckets = [b for b in popular_files]
|
||||||
@@ -190,7 +193,7 @@ def test_bucket_response_can_be_iterated_over(agg_response) -> None:
|
|||||||
assert buckets == popular_files.buckets
|
assert buckets == popular_files.buckets
|
||||||
|
|
||||||
|
|
||||||
def test_bucket_keys_get_deserialized(aggs_data, aggs_search) -> None:
|
def test_bucket_keys_get_deserialized(aggs_data: Any, aggs_search: Any) -> None:
|
||||||
class Commit(Document):
|
class Commit(Document):
|
||||||
info = Object(properties={"committed_date": Date()})
|
info = Object(properties={"committed_date": Date()})
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from pytest import raises
|
from pytest import raises
|
||||||
|
|
||||||
@@ -41,16 +42,16 @@ def test_expand__to_dot_is_respected() -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_execute_uses_cache() -> None:
|
def test_execute_uses_cache() -> None:
|
||||||
s = search.Search()
|
s: Any = search.Search()
|
||||||
r = object()
|
r: Any = object()
|
||||||
s._response = r
|
s._response = r
|
||||||
|
|
||||||
assert r is s.execute()
|
assert r is s.execute()
|
||||||
|
|
||||||
|
|
||||||
def test_cache_can_be_ignored(mock_client) -> None:
|
def test_cache_can_be_ignored(mock_client: Any) -> None:
|
||||||
s = search.Search(using="mock")
|
s: Any = search.Search(using="mock")
|
||||||
r = object()
|
r: Any = object()
|
||||||
s._response = r
|
s._response = r
|
||||||
s.execute(ignore_cache=True)
|
s.execute(ignore_cache=True)
|
||||||
|
|
||||||
@@ -58,27 +59,27 @@ def test_cache_can_be_ignored(mock_client) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_iter_iterates_over_hits() -> None:
|
def test_iter_iterates_over_hits() -> None:
|
||||||
s = search.Search()
|
s: Any = search.Search()
|
||||||
s._response = [1, 2, 3]
|
s._response = [1, 2, 3]
|
||||||
|
|
||||||
assert [1, 2, 3] == list(s)
|
assert [1, 2, 3] == list(s)
|
||||||
|
|
||||||
|
|
||||||
def test_cache_isnt_cloned() -> None:
|
def test_cache_isnt_cloned() -> None:
|
||||||
s = search.Search()
|
s: Any = search.Search()
|
||||||
s._response = object()
|
s._response = object()
|
||||||
|
|
||||||
assert not hasattr(s._clone(), "_response")
|
assert not hasattr(s._clone(), "_response")
|
||||||
|
|
||||||
|
|
||||||
def test_search_starts_with_no_query() -> None:
|
def test_search_starts_with_no_query() -> None:
|
||||||
s = search.Search()
|
s: Any = search.Search()
|
||||||
|
|
||||||
assert s.query._proxied is None
|
assert s.query._proxied is None
|
||||||
|
|
||||||
|
|
||||||
def test_search_query_combines_query() -> None:
|
def test_search_query_combines_query() -> None:
|
||||||
s = search.Search()
|
s: Any = search.Search()
|
||||||
|
|
||||||
s2 = s.query("match", f=42)
|
s2 = s.query("match", f=42)
|
||||||
assert s2.query._proxied == query.Match(f=42)
|
assert s2.query._proxied == query.Match(f=42)
|
||||||
@@ -90,7 +91,7 @@ def test_search_query_combines_query() -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_query_can_be_assigned_to() -> None:
|
def test_query_can_be_assigned_to() -> None:
|
||||||
s = search.Search()
|
s: Any = search.Search()
|
||||||
|
|
||||||
q = Q("match", title="python")
|
q = Q("match", title="python")
|
||||||
s.query = q
|
s.query = q
|
||||||
@@ -98,8 +99,8 @@ def test_query_can_be_assigned_to() -> None:
|
|||||||
assert s.query._proxied is q
|
assert s.query._proxied is q
|
||||||
|
|
||||||
|
|
||||||
def test_query_can_be_wrapped():
|
def test_query_can_be_wrapped() -> None:
|
||||||
s = search.Search().query("match", title="python")
|
s: Any = search.Search().query("match", title="python")
|
||||||
|
|
||||||
s.query = Q("function_score", query=s.query, field_value_factor={"field": "rating"})
|
s.query = Q("function_score", query=s.query, field_value_factor={"field": "rating"})
|
||||||
|
|
||||||
@@ -114,9 +115,9 @@ def test_query_can_be_wrapped():
|
|||||||
|
|
||||||
|
|
||||||
def test_using() -> None:
|
def test_using() -> None:
|
||||||
o = object()
|
o: Any = object()
|
||||||
o2 = object()
|
o2: Any = object()
|
||||||
s = search.Search(using=o)
|
s: Any = search.Search(using=o)
|
||||||
assert s._using is o
|
assert s._using is o
|
||||||
s2 = s.using(o2)
|
s2 = s.using(o2)
|
||||||
assert s._using is o
|
assert s._using is o
|
||||||
@@ -124,27 +125,27 @@ def test_using() -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_methods_are_proxied_to_the_query() -> None:
|
def test_methods_are_proxied_to_the_query() -> None:
|
||||||
s = search.Search().query("match_all")
|
s: Any = search.Search().query("match_all")
|
||||||
|
|
||||||
assert s.query.to_dict() == {"match_all": {}}
|
assert s.query.to_dict() == {"match_all": {}}
|
||||||
|
|
||||||
|
|
||||||
def test_query_always_returns_search() -> None:
|
def test_query_always_returns_search() -> None:
|
||||||
s = search.Search()
|
s: Any = search.Search()
|
||||||
|
|
||||||
assert isinstance(s.query("match", f=42), search.Search)
|
assert isinstance(s.query("match", f=42), search.Search)
|
||||||
|
|
||||||
|
|
||||||
def test_source_copied_on_clone() -> None:
|
def test_source_copied_on_clone() -> None:
|
||||||
s = search.Search().source(False)
|
s: Any = search.Search().source(False)
|
||||||
assert s._clone()._source == s._source
|
assert s._clone()._source == s._source
|
||||||
assert s._clone()._source is False
|
assert s._clone()._source is False
|
||||||
|
|
||||||
s2 = search.Search().source([])
|
s2: Any = search.Search().source([])
|
||||||
assert s2._clone()._source == s2._source
|
assert s2._clone()._source == s2._source
|
||||||
assert s2._source == []
|
assert s2._source == []
|
||||||
|
|
||||||
s3 = search.Search().source(["some", "fields"])
|
s3: Any = search.Search().source(["some", "fields"])
|
||||||
assert s3._clone()._source == s3._source
|
assert s3._clone()._source == s3._source
|
||||||
assert s3._clone()._source == ["some", "fields"]
|
assert s3._clone()._source == ["some", "fields"]
|
||||||
|
|
||||||
@@ -152,15 +153,15 @@ def test_source_copied_on_clone() -> None:
|
|||||||
def test_copy_clones() -> None:
|
def test_copy_clones() -> None:
|
||||||
from copy import copy
|
from copy import copy
|
||||||
|
|
||||||
s1 = search.Search().source(["some", "fields"])
|
s1: Any = search.Search().source(["some", "fields"])
|
||||||
s2 = copy(s1)
|
s2: Any = copy(s1)
|
||||||
|
|
||||||
assert s1 == s2
|
assert s1 == s2
|
||||||
assert s1 is not s2
|
assert s1 is not s2
|
||||||
|
|
||||||
|
|
||||||
def test_aggs_allow_two_metric() -> None:
|
def test_aggs_allow_two_metric() -> None:
|
||||||
s = search.Search()
|
s: Any = search.Search()
|
||||||
|
|
||||||
s.aggs.metric("a", "max", field="a").metric("b", "max", field="b")
|
s.aggs.metric("a", "max", field="a").metric("b", "max", field="b")
|
||||||
|
|
||||||
@@ -169,8 +170,8 @@ def test_aggs_allow_two_metric() -> None:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_aggs_get_copied_on_change():
|
def test_aggs_get_copied_on_change() -> None:
|
||||||
s = search.Search().query("match_all")
|
s: Any = search.Search().query("match_all")
|
||||||
s.aggs.bucket("per_tag", "terms", field="f").metric(
|
s.aggs.bucket("per_tag", "terms", field="f").metric(
|
||||||
"max_score", "max", field="score"
|
"max_score", "max", field="score"
|
||||||
)
|
)
|
||||||
@@ -182,7 +183,7 @@ def test_aggs_get_copied_on_change():
|
|||||||
s4 = s3._clone()
|
s4 = s3._clone()
|
||||||
s4.aggs.metric("max_score", "max", field="score")
|
s4.aggs.metric("max_score", "max", field="score")
|
||||||
|
|
||||||
d = {
|
d: Any = {
|
||||||
"query": {"match_all": {}},
|
"query": {"match_all": {}},
|
||||||
"aggs": {
|
"aggs": {
|
||||||
"per_tag": {
|
"per_tag": {
|
||||||
@@ -245,7 +246,7 @@ def test_doc_type_document_class() -> None:
|
|||||||
assert s._doc_type_map == {}
|
assert s._doc_type_map == {}
|
||||||
|
|
||||||
|
|
||||||
def test_sort():
|
def test_sort() -> None:
|
||||||
s = search.Search()
|
s = search.Search()
|
||||||
s = s.sort("fielda", "-fieldb")
|
s = s.sort("fielda", "-fieldb")
|
||||||
|
|
||||||
@@ -267,7 +268,7 @@ def test_sort_by_score() -> None:
|
|||||||
s.sort("-_score")
|
s.sort("-_score")
|
||||||
|
|
||||||
|
|
||||||
def test_collapse():
|
def test_collapse() -> None:
|
||||||
s = search.Search()
|
s = search.Search()
|
||||||
|
|
||||||
inner_hits = {"name": "most_recent", "size": 5, "sort": [{"@timestamp": "desc"}]}
|
inner_hits = {"name": "most_recent", "size": 5, "sort": [{"@timestamp": "desc"}]}
|
||||||
@@ -315,7 +316,7 @@ def test_index() -> None:
|
|||||||
assert {"from": 3, "size": 1} == s[3].to_dict()
|
assert {"from": 3, "size": 1} == s[3].to_dict()
|
||||||
|
|
||||||
|
|
||||||
def test_search_to_dict():
|
def test_search_to_dict() -> None:
|
||||||
s = search.Search()
|
s = search.Search()
|
||||||
assert {} == s.to_dict()
|
assert {} == s.to_dict()
|
||||||
|
|
||||||
@@ -344,7 +345,7 @@ def test_search_to_dict():
|
|||||||
assert {"size": 5, "from": 42} == s.to_dict()
|
assert {"size": 5, "from": 42} == s.to_dict()
|
||||||
|
|
||||||
|
|
||||||
def test_complex_example():
|
def test_complex_example() -> None:
|
||||||
s = search.Search()
|
s = search.Search()
|
||||||
s = (
|
s = (
|
||||||
s.query("match", title="python")
|
s.query("match", title="python")
|
||||||
@@ -395,7 +396,7 @@ def test_complex_example():
|
|||||||
} == s.to_dict()
|
} == s.to_dict()
|
||||||
|
|
||||||
|
|
||||||
def test_reverse():
|
def test_reverse() -> None:
|
||||||
d = {
|
d = {
|
||||||
"query": {
|
"query": {
|
||||||
"filtered": {
|
"filtered": {
|
||||||
@@ -451,7 +452,7 @@ def test_from_dict_doesnt_need_query() -> None:
|
|||||||
assert {"size": 5} == s.to_dict()
|
assert {"size": 5} == s.to_dict()
|
||||||
|
|
||||||
|
|
||||||
def test_params_being_passed_to_search(mock_client) -> None:
|
def test_params_being_passed_to_search(mock_client: Any) -> None:
|
||||||
s = search.Search(using="mock")
|
s = search.Search(using="mock")
|
||||||
s = s.params(routing="42")
|
s = s.params(routing="42")
|
||||||
s.execute()
|
s.execute()
|
||||||
@@ -473,7 +474,7 @@ def test_source() -> None:
|
|||||||
).source(["f1", "f2"]).to_dict()
|
).source(["f1", "f2"]).to_dict()
|
||||||
|
|
||||||
|
|
||||||
def test_source_on_clone():
|
def test_source_on_clone() -> None:
|
||||||
assert {
|
assert {
|
||||||
"_source": {"includes": ["foo.bar.*"], "excludes": ["foo.one"]},
|
"_source": {"includes": ["foo.bar.*"], "excludes": ["foo.one"]},
|
||||||
"query": {"bool": {"filter": [{"term": {"title": "python"}}]}},
|
"query": {"bool": {"filter": [{"term": {"title": "python"}}]}},
|
||||||
@@ -498,7 +499,7 @@ def test_source_on_clear() -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_suggest_accepts_global_text():
|
def test_suggest_accepts_global_text() -> None:
|
||||||
s = search.Search.from_dict(
|
s = search.Search.from_dict(
|
||||||
{
|
{
|
||||||
"suggest": {
|
"suggest": {
|
||||||
@@ -520,7 +521,7 @@ def test_suggest_accepts_global_text():
|
|||||||
} == s.to_dict()
|
} == s.to_dict()
|
||||||
|
|
||||||
|
|
||||||
def test_suggest():
|
def test_suggest() -> None:
|
||||||
s = search.Search()
|
s = search.Search()
|
||||||
s = s.suggest("my_suggestion", "pyhton", term={"field": "title"})
|
s = s.suggest("my_suggestion", "pyhton", term={"field": "title"})
|
||||||
|
|
||||||
@@ -542,7 +543,7 @@ def test_exclude() -> None:
|
|||||||
} == s.to_dict()
|
} == s.to_dict()
|
||||||
|
|
||||||
|
|
||||||
def test_delete_by_query(mock_client) -> None:
|
def test_delete_by_query(mock_client: Any) -> None:
|
||||||
s = search.Search(using="mock").query("match", lang="java")
|
s = search.Search(using="mock").query("match", lang="java")
|
||||||
s.delete()
|
s.delete()
|
||||||
|
|
||||||
@@ -551,7 +552,7 @@ def test_delete_by_query(mock_client) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_update_from_dict():
|
def test_update_from_dict() -> None:
|
||||||
s = search.Search()
|
s = search.Search()
|
||||||
s.update_from_dict({"indices_boost": [{"important-documents": 2}]})
|
s.update_from_dict({"indices_boost": [{"important-documents": 2}]})
|
||||||
s.update_from_dict({"_source": ["id", "name"]})
|
s.update_from_dict({"_source": ["id", "name"]})
|
||||||
@@ -562,7 +563,7 @@ def test_update_from_dict():
|
|||||||
} == s.to_dict()
|
} == s.to_dict()
|
||||||
|
|
||||||
|
|
||||||
def test_rescore_query_to_dict():
|
def test_rescore_query_to_dict() -> None:
|
||||||
s = search.Search(index="index-name")
|
s = search.Search(index="index-name")
|
||||||
|
|
||||||
positive_query = Q(
|
positive_query = Q(
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from opensearchpy import Q, UpdateByQuery
|
from opensearchpy import Q, UpdateByQuery
|
||||||
from opensearchpy.helpers.response import UpdateByQueryResponse
|
from opensearchpy.helpers.response import UpdateByQueryResponse
|
||||||
@@ -37,7 +38,7 @@ def test_ubq_starts_with_no_query() -> None:
|
|||||||
assert ubq.query._proxied is None
|
assert ubq.query._proxied is None
|
||||||
|
|
||||||
|
|
||||||
def test_ubq_to_dict():
|
def test_ubq_to_dict() -> None:
|
||||||
ubq = UpdateByQuery()
|
ubq = UpdateByQuery()
|
||||||
assert {} == ubq.to_dict()
|
assert {} == ubq.to_dict()
|
||||||
|
|
||||||
@@ -53,7 +54,7 @@ def test_ubq_to_dict():
|
|||||||
assert {"extra_q": {"term": {"category": "conference"}}} == ubq.to_dict()
|
assert {"extra_q": {"term": {"category": "conference"}}} == ubq.to_dict()
|
||||||
|
|
||||||
|
|
||||||
def test_complex_example():
|
def test_complex_example() -> None:
|
||||||
ubq = UpdateByQuery()
|
ubq = UpdateByQuery()
|
||||||
ubq = (
|
ubq = (
|
||||||
ubq.query("match", title="python")
|
ubq.query("match", title="python")
|
||||||
@@ -104,7 +105,7 @@ def test_exclude() -> None:
|
|||||||
} == ubq.to_dict()
|
} == ubq.to_dict()
|
||||||
|
|
||||||
|
|
||||||
def test_reverse():
|
def test_reverse() -> None:
|
||||||
d = {
|
d = {
|
||||||
"query": {
|
"query": {
|
||||||
"filtered": {
|
"filtered": {
|
||||||
@@ -146,7 +147,7 @@ def test_from_dict_doesnt_need_query() -> None:
|
|||||||
assert {"script": {"source": "test"}} == ubq.to_dict()
|
assert {"script": {"source": "test"}} == ubq.to_dict()
|
||||||
|
|
||||||
|
|
||||||
def test_params_being_passed_to_search(mock_client) -> None:
|
def test_params_being_passed_to_search(mock_client: Any) -> None:
|
||||||
ubq = UpdateByQuery(using="mock")
|
ubq = UpdateByQuery(using="mock")
|
||||||
ubq = ubq.params(routing="42")
|
ubq = ubq.params(routing="42")
|
||||||
ubq.execute()
|
ubq.execute()
|
||||||
@@ -156,7 +157,7 @@ def test_params_being_passed_to_search(mock_client) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_overwrite_script():
|
def test_overwrite_script() -> None:
|
||||||
ubq = UpdateByQuery()
|
ubq = UpdateByQuery()
|
||||||
ubq = ubq.script(
|
ubq = ubq.script(
|
||||||
source="ctx._source.likes += params.f", lang="painless", params={"f": 3}
|
source="ctx._source.likes += params.f", lang="painless", params={"f": 3}
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ def test_attrlist_slice() -> None:
|
|||||||
assert isinstance(ls[:][0], MyAttrDict)
|
assert isinstance(ls[:][0], MyAttrDict)
|
||||||
|
|
||||||
|
|
||||||
def test_merge():
|
def test_merge() -> None:
|
||||||
a = utils.AttrDict({"a": {"b": 42, "c": 47}})
|
a = utils.AttrDict({"a": {"b": 42, "c": 47}})
|
||||||
b = {"a": {"b": 123, "d": -12}, "e": [1, 2, 3]}
|
b = {"a": {"b": 123, "d": -12}, "e": [1, 2, 3]}
|
||||||
|
|
||||||
@@ -101,7 +101,7 @@ def test_serializer_deals_with_Attr_versions() -> None:
|
|||||||
|
|
||||||
def test_serializer_deals_with_objects_with_to_dict() -> None:
|
def test_serializer_deals_with_objects_with_to_dict() -> None:
|
||||||
class MyClass(object):
|
class MyClass(object):
|
||||||
def to_dict(self):
|
def to_dict(self) -> int:
|
||||||
return 42
|
return 42
|
||||||
|
|
||||||
assert serializer.serializer.dumps(MyClass()) == "42"
|
assert serializer.serializer.dumps(MyClass()) == "42"
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from pytest import raises
|
from pytest import raises
|
||||||
|
|
||||||
@@ -43,8 +44,8 @@ from opensearchpy.exceptions import ValidationException
|
|||||||
|
|
||||||
|
|
||||||
class Author(InnerDoc):
|
class Author(InnerDoc):
|
||||||
name = Text(required=True)
|
name: Any = Text(required=True)
|
||||||
email = Text(required=True)
|
email: Any = Text(required=True)
|
||||||
|
|
||||||
def clean(self) -> None:
|
def clean(self) -> None:
|
||||||
print(self, type(self), self.name)
|
print(self, type(self), self.name)
|
||||||
@@ -63,7 +64,7 @@ class BlogPostWithStatus(Document):
|
|||||||
|
|
||||||
|
|
||||||
class AutoNowDate(Date):
|
class AutoNowDate(Date):
|
||||||
def clean(self, data):
|
def clean(self, data: Any) -> Any:
|
||||||
if data is None:
|
if data is None:
|
||||||
data = datetime.now()
|
data = datetime.now()
|
||||||
return super(AutoNowDate, self).clean(data)
|
return super(AutoNowDate, self).clean(data)
|
||||||
@@ -78,7 +79,7 @@ def test_required_int_can_be_0() -> None:
|
|||||||
class DT(Document):
|
class DT(Document):
|
||||||
i = Integer(required=True)
|
i = Integer(required=True)
|
||||||
|
|
||||||
dt = DT(i=0)
|
dt: Any = DT(i=0)
|
||||||
assert dt.full_clean() is None
|
assert dt.full_clean() is None
|
||||||
|
|
||||||
|
|
||||||
@@ -95,12 +96,12 @@ def test_validation_works_for_lists_of_values() -> None:
|
|||||||
class DT(Document):
|
class DT(Document):
|
||||||
i = Date(required=True)
|
i = Date(required=True)
|
||||||
|
|
||||||
dt = DT(i=[datetime.now(), "not date"])
|
dt1: Any = DT(i=[datetime.now(), "not date"])
|
||||||
with raises(ValidationException):
|
with raises(ValidationException):
|
||||||
dt.full_clean()
|
dt1.full_clean()
|
||||||
|
|
||||||
dt = DT(i=[datetime.now(), datetime.now()])
|
dt2: Any = DT(i=[datetime.now(), datetime.now()])
|
||||||
assert None is dt.full_clean()
|
assert None is dt2.full_clean()
|
||||||
|
|
||||||
|
|
||||||
def test_field_with_custom_clean() -> None:
|
def test_field_with_custom_clean() -> None:
|
||||||
@@ -111,29 +112,29 @@ def test_field_with_custom_clean() -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_empty_object() -> None:
|
def test_empty_object() -> None:
|
||||||
d = BlogPost(authors=[{"name": "Guian", "email": "[email protected]"}])
|
d: Any = BlogPost(authors=[{"name": "Guian", "email": "[email protected]"}])
|
||||||
d.inner = {}
|
d.inner = {}
|
||||||
|
|
||||||
d.full_clean()
|
d.full_clean()
|
||||||
|
|
||||||
|
|
||||||
def test_missing_required_field_raises_validation_exception() -> None:
|
def test_missing_required_field_raises_validation_exception() -> None:
|
||||||
d = BlogPost()
|
d1: Any = BlogPost()
|
||||||
with raises(ValidationException):
|
with raises(ValidationException):
|
||||||
d.full_clean()
|
d1.full_clean()
|
||||||
|
|
||||||
d = BlogPost()
|
d2: Any = BlogPost()
|
||||||
d.authors.append({"name": "Guian"})
|
d2.authors.append({"name": "Guian"})
|
||||||
with raises(ValidationException):
|
with raises(ValidationException):
|
||||||
d.full_clean()
|
d2.full_clean()
|
||||||
|
|
||||||
d = BlogPost()
|
d3: Any = BlogPost()
|
||||||
d.authors.append({"name": "Guian", "email": "[email protected]"})
|
d3.authors.append({"name": "Guian", "email": "[email protected]"})
|
||||||
d.full_clean()
|
d3.full_clean()
|
||||||
|
|
||||||
|
|
||||||
def test_boolean_doesnt_treat_false_as_empty() -> None:
|
def test_boolean_doesnt_treat_false_as_empty() -> None:
|
||||||
d = BlogPostWithStatus()
|
d: Any = BlogPostWithStatus()
|
||||||
with raises(ValidationException):
|
with raises(ValidationException):
|
||||||
d.full_clean()
|
d.full_clean()
|
||||||
d.published = False
|
d.published = False
|
||||||
@@ -143,7 +144,9 @@ def test_boolean_doesnt_treat_false_as_empty() -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_custom_validation_on_nested_gets_run() -> None:
|
def test_custom_validation_on_nested_gets_run() -> None:
|
||||||
d = BlogPost(authors=[Author(name="Guian", email="[email protected]")], created=None)
|
d: Any = BlogPost(
|
||||||
|
authors=[Author(name="Guian", email="[email protected]")], created=None
|
||||||
|
)
|
||||||
|
|
||||||
assert isinstance(d.authors[0], Author)
|
assert isinstance(d.authors[0], Author)
|
||||||
|
|
||||||
@@ -152,7 +155,7 @@ def test_custom_validation_on_nested_gets_run() -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_accessing_known_fields_returns_empty_value() -> None:
|
def test_accessing_known_fields_returns_empty_value() -> None:
|
||||||
d = BlogPost()
|
d: Any = BlogPost()
|
||||||
|
|
||||||
assert [] == d.authors
|
assert [] == d.authors
|
||||||
|
|
||||||
@@ -162,7 +165,7 @@ def test_accessing_known_fields_returns_empty_value() -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_empty_values_are_not_serialized() -> None:
|
def test_empty_values_are_not_serialized() -> None:
|
||||||
d = BlogPost(
|
d: Any = BlogPost(
|
||||||
authors=[{"name": "Guian", "email": "[email protected]"}], created=None
|
authors=[{"name": "Guian", "email": "[email protected]"}], created=None
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -26,13 +26,14 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from opensearchpy import Range
|
from opensearchpy import Range
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize( # type: ignore
|
||||||
"kwargs, item",
|
"kwargs, item",
|
||||||
[
|
[
|
||||||
({}, 1),
|
({}, 1),
|
||||||
@@ -44,11 +45,11 @@ from opensearchpy import Range
|
|||||||
({"gt": datetime.now() - timedelta(seconds=10)}, datetime.now()),
|
({"gt": datetime.now() - timedelta(seconds=10)}, datetime.now()),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_range_contains(kwargs, item) -> None:
|
def test_range_contains(kwargs: Any, item: Any) -> None:
|
||||||
assert item in Range(**kwargs)
|
assert item in Range(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize( # type: ignore
|
||||||
"kwargs, item",
|
"kwargs, item",
|
||||||
[
|
[
|
||||||
({"gt": -1}, -1),
|
({"gt": -1}, -1),
|
||||||
@@ -58,11 +59,11 @@ def test_range_contains(kwargs, item) -> None:
|
|||||||
({"lte": datetime.now() - timedelta(seconds=10)}, datetime.now()),
|
({"lte": datetime.now() - timedelta(seconds=10)}, datetime.now()),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_range_not_contains(kwargs, item):
|
def test_range_not_contains(kwargs: Any, item: Any) -> None:
|
||||||
assert item not in Range(**kwargs)
|
assert item not in Range(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize( # type: ignore
|
||||||
"args,kwargs",
|
"args,kwargs",
|
||||||
[
|
[
|
||||||
(({},), {"lt": 42}),
|
(({},), {"lt": 42}),
|
||||||
@@ -72,12 +73,12 @@ def test_range_not_contains(kwargs, item):
|
|||||||
((), {"gt": 1, "gte": 1}),
|
((), {"gt": 1, "gte": 1}),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_range_raises_value_error_on_wrong_params(args, kwargs) -> None:
|
def test_range_raises_value_error_on_wrong_params(args: Any, kwargs: Any) -> None:
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
Range(*args, **kwargs)
|
Range(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize( # type: ignore
|
||||||
"range,lower,inclusive",
|
"range,lower,inclusive",
|
||||||
[
|
[
|
||||||
(Range(gt=1), 1, False),
|
(Range(gt=1), 1, False),
|
||||||
@@ -86,11 +87,11 @@ def test_range_raises_value_error_on_wrong_params(args, kwargs) -> None:
|
|||||||
(Range(lt=42), None, False),
|
(Range(lt=42), None, False),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_range_lower(range, lower, inclusive) -> None:
|
def test_range_lower(range: Any, lower: Any, inclusive: Any) -> None:
|
||||||
assert (lower, inclusive) == range.lower
|
assert (lower, inclusive) == range.lower
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize( # type: ignore
|
||||||
"range,upper,inclusive",
|
"range,upper,inclusive",
|
||||||
[
|
[
|
||||||
(Range(lt=1), 1, False),
|
(Range(lt=1), 1, False),
|
||||||
@@ -99,5 +100,5 @@ def test_range_lower(range, lower, inclusive) -> None:
|
|||||||
(Range(gt=42), None, False),
|
(Range(gt=42), None, False),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_range_upper(range, upper, inclusive) -> None:
|
def test_range_upper(range: Any, upper: Any, inclusive: Any) -> None:
|
||||||
assert (upper, inclusive) == range.upper
|
assert (upper, inclusive) == range.upper
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import sys
|
|||||||
import uuid
|
import uuid
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import numpy as np
|
import numpy as np
|
||||||
@@ -212,7 +213,7 @@ class TestTextSerializer(TestCase):
|
|||||||
|
|
||||||
|
|
||||||
class TestDeserializer(TestCase):
|
class TestDeserializer(TestCase):
|
||||||
def setup_method(self, _) -> None:
|
def setup_method(self, _: Any) -> None:
|
||||||
self.de = Deserializer(DEFAULT_SERIALIZERS)
|
self.de = Deserializer(DEFAULT_SERIALIZERS)
|
||||||
|
|
||||||
def test_deserializes_json_by_default(self) -> None:
|
def test_deserializes_json_by_default(self) -> None:
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
from unittest import SkipTest
|
from unittest import SkipTest
|
||||||
|
|
||||||
from opensearchpy.helpers import test
|
from opensearchpy.helpers import test
|
||||||
@@ -34,7 +35,7 @@ from opensearchpy.helpers.test import OpenSearchTestCase as BaseTestCase
|
|||||||
client = None
|
client = None
|
||||||
|
|
||||||
|
|
||||||
def get_client(**kwargs):
|
def get_client(**kwargs: Any) -> Any:
|
||||||
global client
|
global client
|
||||||
if client is False:
|
if client is False:
|
||||||
raise SkipTest("No client is available")
|
raise SkipTest("No client is available")
|
||||||
@@ -66,5 +67,5 @@ def setup_module() -> None:
|
|||||||
|
|
||||||
class OpenSearchTestCase(BaseTestCase):
|
class OpenSearchTestCase(BaseTestCase):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _get_client(**kwargs):
|
def _get_client(**kwargs: Any) -> Any:
|
||||||
return get_client(**kwargs)
|
return get_client(**kwargs)
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@@ -40,11 +41,11 @@ from ..utils import wipe_cluster
|
|||||||
# Used for
|
# Used for
|
||||||
OPENSEARCH_VERSION = ""
|
OPENSEARCH_VERSION = ""
|
||||||
OPENSEARCH_BUILD_HASH = ""
|
OPENSEARCH_BUILD_HASH = ""
|
||||||
OPENSEARCH_REST_API_TESTS = []
|
OPENSEARCH_REST_API_TESTS: Any = []
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session") # type: ignore
|
||||||
def sync_client_factory():
|
def sync_client_factory() -> Any:
|
||||||
client = None
|
client = None
|
||||||
try:
|
try:
|
||||||
# Configure the client optionally with an HTTP conn class
|
# Configure the client optionally with an HTTP conn class
|
||||||
@@ -63,7 +64,7 @@ def sync_client_factory():
|
|||||||
# We do this little dance with the URL to force
|
# We do this little dance with the URL to force
|
||||||
# Requests to respect 'headers: None' within rest API spec tests.
|
# Requests to respect 'headers: None' within rest API spec tests.
|
||||||
client = opensearchpy.OpenSearch(
|
client = opensearchpy.OpenSearch(
|
||||||
OPENSEARCH_URL.replace("elastic:changeme@", ""), **kw
|
OPENSEARCH_URL.replace("elastic:changeme@", ""), **kw # type: ignore
|
||||||
)
|
)
|
||||||
|
|
||||||
# Wait for the cluster to report a status of 'yellow'
|
# Wait for the cluster to report a status of 'yellow'
|
||||||
@@ -83,8 +84,8 @@ def sync_client_factory():
|
|||||||
client.close()
|
client.close()
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="function")
|
@pytest.fixture(scope="function") # type: ignore
|
||||||
def sync_client(sync_client_factory):
|
def sync_client(sync_client_factory: Any) -> Any:
|
||||||
try:
|
try:
|
||||||
yield sync_client_factory
|
yield sync_client_factory
|
||||||
finally:
|
finally:
|
||||||
|
|||||||
@@ -27,10 +27,10 @@
|
|||||||
|
|
||||||
import re
|
import re
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from pytest import fixture
|
from pytest import fixture
|
||||||
|
|
||||||
from opensearchpy.client import OpenSearch
|
|
||||||
from opensearchpy.connection.connections import add_connection
|
from opensearchpy.connection.connections import add_connection
|
||||||
from opensearchpy.helpers import bulk
|
from opensearchpy.helpers import bulk
|
||||||
from opensearchpy.helpers.test import get_test_client
|
from opensearchpy.helpers.test import get_test_client
|
||||||
@@ -45,32 +45,32 @@ from .test_data import (
|
|||||||
from .test_document import Comment, History, PullRequest, User
|
from .test_document import Comment, History, PullRequest, User
|
||||||
|
|
||||||
|
|
||||||
@fixture(scope="session")
|
@fixture(scope="session") # type: ignore
|
||||||
def client() -> OpenSearch:
|
def client() -> Any:
|
||||||
client = get_test_client(verify_certs=False, http_auth=("admin", "admin"))
|
client = get_test_client(verify_certs=False, http_auth=("admin", "admin"))
|
||||||
add_connection("default", client)
|
add_connection("default", client)
|
||||||
return client
|
return client
|
||||||
|
|
||||||
|
|
||||||
@fixture(scope="session")
|
@fixture(scope="session") # type: ignore
|
||||||
def opensearch_version(client):
|
def opensearch_version(client: Any) -> Any:
|
||||||
info = client.info()
|
info = client.info()
|
||||||
print(info)
|
print(info)
|
||||||
yield tuple(
|
yield tuple(
|
||||||
int(x)
|
int(x)
|
||||||
for x in re.match(r"^([0-9.]+)", info["version"]["number"]).group(1).split(".")
|
for x in re.match(r"^([0-9.]+)", info["version"]["number"]).group(1).split(".") # type: ignore
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@fixture
|
@fixture # type: ignore
|
||||||
def write_client(client):
|
def write_client(client: Any) -> Any:
|
||||||
yield client
|
yield client
|
||||||
client.indices.delete("test-*", ignore=404)
|
client.indices.delete("test-*", ignore=404)
|
||||||
client.indices.delete_template("test-template", ignore=404)
|
client.indices.delete_template("test-template", ignore=404)
|
||||||
|
|
||||||
|
|
||||||
@fixture(scope="session")
|
@fixture(scope="session") # type: ignore
|
||||||
def data_client(client):
|
def data_client(client: Any) -> Any:
|
||||||
# create mappings
|
# create mappings
|
||||||
create_git_index(client, "git")
|
create_git_index(client, "git")
|
||||||
create_flat_git_index(client, "flat-git")
|
create_flat_git_index(client, "flat-git")
|
||||||
@@ -82,8 +82,8 @@ def data_client(client):
|
|||||||
client.indices.delete("flat-git", ignore=404)
|
client.indices.delete("flat-git", ignore=404)
|
||||||
|
|
||||||
|
|
||||||
@fixture
|
@fixture # type: ignore
|
||||||
def pull_request(write_client):
|
def pull_request(write_client: Any) -> Any:
|
||||||
PullRequest.init()
|
PullRequest.init()
|
||||||
pr = PullRequest(
|
pr = PullRequest(
|
||||||
_id=42,
|
_id=42,
|
||||||
@@ -106,8 +106,8 @@ def pull_request(write_client):
|
|||||||
return pr
|
return pr
|
||||||
|
|
||||||
|
|
||||||
@fixture
|
@fixture # type: ignore
|
||||||
def setup_ubq_tests(client) -> str:
|
def setup_ubq_tests(client: Any) -> str:
|
||||||
index = "test-git"
|
index = "test-git"
|
||||||
create_git_index(client, index)
|
create_git_index(client, index)
|
||||||
bulk(client, TEST_GIT_DATA, raise_on_error=True, refresh=True)
|
bulk(client, TEST_GIT_DATA, raise_on_error=True, refresh=True)
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
|
||||||
from typing import Tuple
|
from typing import Any
|
||||||
|
|
||||||
from mock import patch
|
from mock import patch
|
||||||
|
|
||||||
@@ -40,9 +40,9 @@ from .. import OpenSearchTestCase
|
|||||||
class FailingBulkClient(object):
|
class FailingBulkClient(object):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
client,
|
client: Any,
|
||||||
fail_at: Tuple[int] = (2,),
|
fail_at: Any = (2,),
|
||||||
fail_with=TransportError(599, "Error!", {}),
|
fail_with: Any = TransportError(599, "Error!", {}),
|
||||||
) -> None:
|
) -> None:
|
||||||
self.client = client
|
self.client = client
|
||||||
self._called = 0
|
self._called = 0
|
||||||
@@ -50,7 +50,7 @@ class FailingBulkClient(object):
|
|||||||
self.transport = client.transport
|
self.transport = client.transport
|
||||||
self._fail_with = fail_with
|
self._fail_with = fail_with
|
||||||
|
|
||||||
def bulk(self, *args, **kwargs):
|
def bulk(self, *args: Any, **kwargs: Any) -> Any:
|
||||||
self._called += 1
|
self._called += 1
|
||||||
if self._called in self._fail_at:
|
if self._called in self._fail_at:
|
||||||
raise self._fail_with
|
raise self._fail_with
|
||||||
@@ -98,7 +98,7 @@ class TestStreamingBulk(OpenSearchTestCase):
|
|||||||
else:
|
else:
|
||||||
assert False, "exception should have been raised"
|
assert False, "exception should have been raised"
|
||||||
|
|
||||||
def test_different_op_types(self):
|
def test_different_op_types(self) -> Any:
|
||||||
if self.opensearch_version() < (0, 90, 1):
|
if self.opensearch_version() < (0, 90, 1):
|
||||||
raise SkipTest("update supported since 0.90.1")
|
raise SkipTest("update supported since 0.90.1")
|
||||||
self.client.index(index="i", id=45, body={})
|
self.client.index(index="i", id=45, body={})
|
||||||
@@ -218,7 +218,7 @@ class TestStreamingBulk(OpenSearchTestCase):
|
|||||||
fail_with=TransportError(429, "Rejected!", {}),
|
fail_with=TransportError(429, "Rejected!", {}),
|
||||||
)
|
)
|
||||||
|
|
||||||
def streaming_bulk():
|
def streaming_bulk() -> Any:
|
||||||
results = list(
|
results = list(
|
||||||
helpers.streaming_bulk(
|
helpers.streaming_bulk(
|
||||||
failing_client,
|
failing_client,
|
||||||
@@ -271,7 +271,7 @@ class TestBulk(OpenSearchTestCase):
|
|||||||
self.assertEqual(0, failed)
|
self.assertEqual(0, failed)
|
||||||
self.assertEqual(100, self.client.count(index="test-index")["count"])
|
self.assertEqual(100, self.client.count(index="test-index")["count"])
|
||||||
|
|
||||||
def test_errors_are_reported_correctly(self):
|
def test_errors_are_reported_correctly(self) -> None:
|
||||||
self.client.indices.create(
|
self.client.indices.create(
|
||||||
"i",
|
"i",
|
||||||
{
|
{
|
||||||
@@ -316,7 +316,7 @@ class TestBulk(OpenSearchTestCase):
|
|||||||
index="i",
|
index="i",
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_ignore_error_if_raised(self):
|
def test_ignore_error_if_raised(self) -> None:
|
||||||
# ignore the status code 400 in tuple
|
# ignore the status code 400 in tuple
|
||||||
helpers.bulk(
|
helpers.bulk(
|
||||||
self.client, [{"a": 42}, {"a": "c"}], index="i", ignore_status=(400,)
|
self.client, [{"a": 42}, {"a": "c"}], index="i", ignore_status=(400,)
|
||||||
@@ -349,7 +349,7 @@ class TestBulk(OpenSearchTestCase):
|
|||||||
failing_client = FailingBulkClient(self.client)
|
failing_client = FailingBulkClient(self.client)
|
||||||
helpers.bulk(failing_client, [{"a": 42}], index="i", ignore_status=(599,))
|
helpers.bulk(failing_client, [{"a": 42}], index="i", ignore_status=(599,))
|
||||||
|
|
||||||
def test_errors_are_collected_properly(self):
|
def test_errors_are_collected_properly(self) -> None:
|
||||||
self.client.indices.create(
|
self.client.indices.create(
|
||||||
"i",
|
"i",
|
||||||
{
|
{
|
||||||
@@ -384,12 +384,12 @@ class TestScan(OpenSearchTestCase):
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
def teardown_method(self, m) -> None:
|
def teardown_method(self, m: Any) -> None:
|
||||||
self.client.transport.perform_request("DELETE", "/_search/scroll/_all")
|
self.client.transport.perform_request("DELETE", "/_search/scroll/_all")
|
||||||
super(TestScan, self).teardown_method(m)
|
super(TestScan, self).teardown_method(m)
|
||||||
|
|
||||||
def test_order_can_be_preserved(self):
|
def test_order_can_be_preserved(self) -> None:
|
||||||
bulk = []
|
bulk: Any = []
|
||||||
for x in range(100):
|
for x in range(100):
|
||||||
bulk.append({"index": {"_index": "test_index", "_id": x}})
|
bulk.append({"index": {"_index": "test_index", "_id": x}})
|
||||||
bulk.append({"answer": x, "correct": x == 42})
|
bulk.append({"answer": x, "correct": x == 42})
|
||||||
@@ -408,8 +408,8 @@ class TestScan(OpenSearchTestCase):
|
|||||||
self.assertEqual(list(map(str, range(100))), list(d["_id"] for d in docs))
|
self.assertEqual(list(map(str, range(100))), list(d["_id"] for d in docs))
|
||||||
self.assertEqual(list(range(100)), list(d["_source"]["answer"] for d in docs))
|
self.assertEqual(list(range(100)), list(d["_source"]["answer"] for d in docs))
|
||||||
|
|
||||||
def test_all_documents_are_read(self):
|
def test_all_documents_are_read(self) -> None:
|
||||||
bulk = []
|
bulk: Any = []
|
||||||
for x in range(100):
|
for x in range(100):
|
||||||
bulk.append({"index": {"_index": "test_index", "_id": x}})
|
bulk.append({"index": {"_index": "test_index", "_id": x}})
|
||||||
bulk.append({"answer": x, "correct": x == 42})
|
bulk.append({"answer": x, "correct": x == 42})
|
||||||
@@ -421,8 +421,8 @@ class TestScan(OpenSearchTestCase):
|
|||||||
self.assertEqual(set(map(str, range(100))), set(d["_id"] for d in docs))
|
self.assertEqual(set(map(str, range(100))), set(d["_id"] for d in docs))
|
||||||
self.assertEqual(set(range(100)), set(d["_source"]["answer"] for d in docs))
|
self.assertEqual(set(range(100)), set(d["_source"]["answer"] for d in docs))
|
||||||
|
|
||||||
def test_scroll_error(self):
|
def test_scroll_error(self) -> None:
|
||||||
bulk = []
|
bulk: Any = []
|
||||||
for x in range(4):
|
for x in range(4):
|
||||||
bulk.append({"index": {"_index": "test_index"}})
|
bulk.append({"index": {"_index": "test_index"}})
|
||||||
bulk.append({"value": x})
|
bulk.append({"value": x})
|
||||||
@@ -456,7 +456,7 @@ class TestScan(OpenSearchTestCase):
|
|||||||
self.assertEqual(len(data), 3)
|
self.assertEqual(len(data), 3)
|
||||||
self.assertEqual(data[-1], {"scroll_data": 42})
|
self.assertEqual(data[-1], {"scroll_data": 42})
|
||||||
|
|
||||||
def test_initial_search_error(self):
|
def test_initial_search_error(self) -> None:
|
||||||
with patch.object(self, "client") as client_mock:
|
with patch.object(self, "client") as client_mock:
|
||||||
client_mock.search.return_value = {
|
client_mock.search.return_value = {
|
||||||
"_scroll_id": "dummy_id",
|
"_scroll_id": "dummy_id",
|
||||||
@@ -491,7 +491,7 @@ class TestScan(OpenSearchTestCase):
|
|||||||
client_mock.scroll.assert_not_called()
|
client_mock.scroll.assert_not_called()
|
||||||
client_mock.clear_scroll.assert_not_called()
|
client_mock.clear_scroll.assert_not_called()
|
||||||
|
|
||||||
def test_scan_auth_kwargs_forwarded(self):
|
def test_scan_auth_kwargs_forwarded(self) -> None:
|
||||||
for key, val in {
|
for key, val in {
|
||||||
"api_key": ("name", "value"),
|
"api_key": ("name", "value"),
|
||||||
"http_auth": ("username", "password"),
|
"http_auth": ("username", "password"),
|
||||||
@@ -510,7 +510,7 @@ class TestScan(OpenSearchTestCase):
|
|||||||
}
|
}
|
||||||
client_mock.clear_scroll.return_value = {}
|
client_mock.clear_scroll.return_value = {}
|
||||||
|
|
||||||
data = list(helpers.scan(self.client, index="test_index", **{key: val}))
|
data = list(helpers.scan(self.client, index="test_index", **{key: val})) # type: ignore
|
||||||
|
|
||||||
self.assertEqual(data, [{"search_data": 1}])
|
self.assertEqual(data, [{"search_data": 1}])
|
||||||
|
|
||||||
@@ -523,7 +523,7 @@ class TestScan(OpenSearchTestCase):
|
|||||||
):
|
):
|
||||||
self.assertEqual(api_mock.call_args[1][key], val)
|
self.assertEqual(api_mock.call_args[1][key], val)
|
||||||
|
|
||||||
def test_scan_auth_kwargs_favor_scroll_kwargs_option(self):
|
def test_scan_auth_kwargs_favor_scroll_kwargs_option(self) -> None:
|
||||||
with patch.object(self, "client") as client_mock:
|
with patch.object(self, "client") as client_mock:
|
||||||
client_mock.search.return_value = {
|
client_mock.search.return_value = {
|
||||||
"_scroll_id": "scroll_id",
|
"_scroll_id": "scroll_id",
|
||||||
@@ -555,8 +555,8 @@ class TestScan(OpenSearchTestCase):
|
|||||||
self.assertEqual(client_mock.scroll.call_args[1]["sort"], "asc")
|
self.assertEqual(client_mock.scroll.call_args[1]["sort"], "asc")
|
||||||
|
|
||||||
@patch("opensearchpy.helpers.actions.logger")
|
@patch("opensearchpy.helpers.actions.logger")
|
||||||
def test_logger(self, logger_mock):
|
def test_logger(self, logger_mock: Any) -> None:
|
||||||
bulk = []
|
bulk: Any = []
|
||||||
for x in range(4):
|
for x in range(4):
|
||||||
bulk.append({"index": {"_index": "test_index"}})
|
bulk.append({"index": {"_index": "test_index"}})
|
||||||
bulk.append({"value": x})
|
bulk.append({"value": x})
|
||||||
@@ -590,8 +590,8 @@ class TestScan(OpenSearchTestCase):
|
|||||||
pass
|
pass
|
||||||
logger_mock.warning.assert_called()
|
logger_mock.warning.assert_called()
|
||||||
|
|
||||||
def test_clear_scroll(self):
|
def test_clear_scroll(self) -> None:
|
||||||
bulk = []
|
bulk: Any = []
|
||||||
for x in range(4):
|
for x in range(4):
|
||||||
bulk.append({"index": {"_index": "test_index"}})
|
bulk.append({"index": {"_index": "test_index"}})
|
||||||
bulk.append({"value": x})
|
bulk.append({"value": x})
|
||||||
@@ -617,7 +617,7 @@ class TestScan(OpenSearchTestCase):
|
|||||||
)
|
)
|
||||||
spy.assert_not_called()
|
spy.assert_not_called()
|
||||||
|
|
||||||
def test_shards_no_skipped_field(self):
|
def test_shards_no_skipped_field(self) -> None:
|
||||||
with patch.object(self, "client") as client_mock:
|
with patch.object(self, "client") as client_mock:
|
||||||
client_mock.search.return_value = {
|
client_mock.search.return_value = {
|
||||||
"_scroll_id": "dummy_id",
|
"_scroll_id": "dummy_id",
|
||||||
@@ -646,8 +646,8 @@ class TestScan(OpenSearchTestCase):
|
|||||||
|
|
||||||
|
|
||||||
class TestReindex(OpenSearchTestCase):
|
class TestReindex(OpenSearchTestCase):
|
||||||
def setup_method(self, _):
|
def setup_method(self, _: Any) -> None:
|
||||||
bulk = []
|
bulk: Any = []
|
||||||
for x in range(100):
|
for x in range(100):
|
||||||
bulk.append({"index": {"_index": "test_index", "_id": x}})
|
bulk.append({"index": {"_index": "test_index", "_id": x}})
|
||||||
bulk.append(
|
bulk.append(
|
||||||
@@ -716,7 +716,7 @@ class TestReindex(OpenSearchTestCase):
|
|||||||
|
|
||||||
|
|
||||||
class TestParentChildReindex(OpenSearchTestCase):
|
class TestParentChildReindex(OpenSearchTestCase):
|
||||||
def setup_method(self, _):
|
def setup_method(self, _: Any) -> None:
|
||||||
body = {
|
body = {
|
||||||
"settings": {"number_of_shards": 1, "number_of_replicas": 0},
|
"settings": {"number_of_shards": 1, "number_of_replicas": 0},
|
||||||
"mappings": {
|
"mappings": {
|
||||||
|
|||||||
@@ -25,10 +25,12 @@
|
|||||||
# specific language governing permissions and limitations
|
# specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from opensearchpy import analyzer, token_filter, tokenizer
|
from opensearchpy import analyzer, token_filter, tokenizer
|
||||||
|
|
||||||
|
|
||||||
def test_simulate_with_just__builtin_tokenizer(client) -> None:
|
def test_simulate_with_just__builtin_tokenizer(client: Any) -> None:
|
||||||
a = analyzer("my-analyzer", tokenizer="keyword")
|
a = analyzer("my-analyzer", tokenizer="keyword")
|
||||||
tokens = a.simulate("Hello World!", using=client).tokens
|
tokens = a.simulate("Hello World!", using=client).tokens
|
||||||
|
|
||||||
@@ -36,7 +38,7 @@ def test_simulate_with_just__builtin_tokenizer(client) -> None:
|
|||||||
assert tokens[0].token == "Hello World!"
|
assert tokens[0].token == "Hello World!"
|
||||||
|
|
||||||
|
|
||||||
def test_simulate_complex(client) -> None:
|
def test_simulate_complex(client: Any) -> None:
|
||||||
a = analyzer(
|
a = analyzer(
|
||||||
"my-analyzer",
|
"my-analyzer",
|
||||||
tokenizer=tokenizer("split_words", "simple_pattern_split", pattern=":"),
|
tokenizer=tokenizer("split_words", "simple_pattern_split", pattern=":"),
|
||||||
@@ -49,7 +51,7 @@ def test_simulate_complex(client) -> None:
|
|||||||
assert ["this", "works"] == [t.token for t in tokens]
|
assert ["this", "works"] == [t.token for t in tokens]
|
||||||
|
|
||||||
|
|
||||||
def test_simulate_builtin(client) -> None:
|
def test_simulate_builtin(client: Any) -> None:
|
||||||
a = analyzer("my-analyzer", "english")
|
a = analyzer("my-analyzer", "english")
|
||||||
tokens = a.simulate("fixes running").tokens
|
tokens = a.simulate("fixes running").tokens
|
||||||
|
|
||||||
|
|||||||
@@ -25,15 +25,17 @@
|
|||||||
# specific language governing permissions and limitations
|
# specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from opensearchpy.helpers.search import Q, Search
|
from opensearchpy.helpers.search import Q, Search
|
||||||
|
|
||||||
|
|
||||||
def test_count_all(data_client) -> None:
|
def test_count_all(data_client: Any) -> None:
|
||||||
s = Search(using=data_client).index("git")
|
s = Search(using=data_client).index("git")
|
||||||
assert 53 == s.count()
|
assert 53 == s.count()
|
||||||
|
|
||||||
|
|
||||||
def test_count_prefetch(data_client, mocker) -> None:
|
def test_count_prefetch(data_client: Any, mocker: Any) -> None:
|
||||||
mocker.spy(data_client, "count")
|
mocker.spy(data_client, "count")
|
||||||
|
|
||||||
search = Search(using=data_client).index("git")
|
search = Search(using=data_client).index("git")
|
||||||
@@ -46,7 +48,7 @@ def test_count_prefetch(data_client, mocker) -> None:
|
|||||||
assert data_client.count.call_count == 1
|
assert data_client.count.call_count == 1
|
||||||
|
|
||||||
|
|
||||||
def test_count_filter(data_client) -> None:
|
def test_count_filter(data_client: Any) -> None:
|
||||||
s = Search(using=data_client).index("git").filter(~Q("exists", field="parent_shas"))
|
s = Search(using=data_client).index("git").filter(~Q("exists", field="parent_shas"))
|
||||||
# initial commit + repo document
|
# initial commit + repo document
|
||||||
assert 2 == s.count()
|
assert 2 == s.count()
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ from __future__ import unicode_literals
|
|||||||
from typing import Any, Dict
|
from typing import Any, Dict
|
||||||
|
|
||||||
|
|
||||||
def create_flat_git_index(client, index):
|
def create_flat_git_index(client: Any, index: Any) -> None:
|
||||||
# we will use user on several places
|
# we will use user on several places
|
||||||
user_mapping = {
|
user_mapping = {
|
||||||
"properties": {"name": {"type": "text", "fields": {"raw": {"type": "keyword"}}}}
|
"properties": {"name": {"type": "text", "fields": {"raw": {"type": "keyword"}}}}
|
||||||
@@ -73,7 +73,7 @@ def create_flat_git_index(client, index):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def create_git_index(client, index):
|
def create_git_index(client: Any, index: Any) -> None:
|
||||||
# we will use user on several places
|
# we will use user on several places
|
||||||
user_mapping = {
|
user_mapping = {
|
||||||
"properties": {"name": {"type": "text", "fields": {"raw": {"type": "keyword"}}}}
|
"properties": {"name": {"type": "text", "fields": {"raw": {"type": "keyword"}}}}
|
||||||
@@ -1095,7 +1095,7 @@ DATA = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def flatten_doc(d) -> Dict[str, Any]:
|
def flatten_doc(d: Any) -> Dict[str, Any]:
|
||||||
src = d["_source"].copy()
|
src = d["_source"].copy()
|
||||||
del src["commit_repo"]
|
del src["commit_repo"]
|
||||||
return {"_index": "flat-git", "_id": d["_id"], "_source": src}
|
return {"_index": "flat-git", "_id": d["_id"], "_source": src}
|
||||||
@@ -1104,7 +1104,7 @@ def flatten_doc(d) -> Dict[str, Any]:
|
|||||||
FLAT_DATA = [flatten_doc(d) for d in DATA if "routing" in d]
|
FLAT_DATA = [flatten_doc(d) for d in DATA if "routing" in d]
|
||||||
|
|
||||||
|
|
||||||
def create_test_git_data(d) -> Dict[str, Any]:
|
def create_test_git_data(d: Any) -> Dict[str, Any]:
|
||||||
src = d["_source"].copy()
|
src = d["_source"].copy()
|
||||||
return {
|
return {
|
||||||
"_index": "test-git",
|
"_index": "test-git",
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from ipaddress import ip_address
|
from ipaddress import ip_address
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from pytest import raises
|
from pytest import raises
|
||||||
@@ -78,7 +79,7 @@ class Repository(Document):
|
|||||||
tags = Keyword()
|
tags = Keyword()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def search(cls):
|
def search(cls, using: Any = None, index: Any = None) -> Any:
|
||||||
return super(Repository, cls).search().filter("term", commit_repo="repo")
|
return super(Repository, cls).search().filter("term", commit_repo="repo")
|
||||||
|
|
||||||
class Index:
|
class Index:
|
||||||
@@ -131,7 +132,7 @@ class SerializationDoc(Document):
|
|||||||
name = "test-serialization"
|
name = "test-serialization"
|
||||||
|
|
||||||
|
|
||||||
def test_serialization(write_client):
|
def test_serialization(write_client: Any) -> None:
|
||||||
SerializationDoc.init()
|
SerializationDoc.init()
|
||||||
write_client.index(
|
write_client.index(
|
||||||
index="test-serialization",
|
index="test-serialization",
|
||||||
@@ -161,7 +162,7 @@ def test_serialization(write_client):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_nested_inner_hits_are_wrapped_properly(pull_request) -> None:
|
def test_nested_inner_hits_are_wrapped_properly(pull_request: Any) -> None:
|
||||||
history_query = Q(
|
history_query = Q(
|
||||||
"nested",
|
"nested",
|
||||||
path="comments.history",
|
path="comments.history",
|
||||||
@@ -189,7 +190,7 @@ def test_nested_inner_hits_are_wrapped_properly(pull_request) -> None:
|
|||||||
assert "score" in history.meta
|
assert "score" in history.meta
|
||||||
|
|
||||||
|
|
||||||
def test_nested_inner_hits_are_deserialized_properly(pull_request) -> None:
|
def test_nested_inner_hits_are_deserialized_properly(pull_request: Any) -> None:
|
||||||
s = PullRequest.search().query(
|
s = PullRequest.search().query(
|
||||||
"nested",
|
"nested",
|
||||||
inner_hits={},
|
inner_hits={},
|
||||||
@@ -204,7 +205,7 @@ def test_nested_inner_hits_are_deserialized_properly(pull_request) -> None:
|
|||||||
assert isinstance(pr.comments[0].created_at, datetime)
|
assert isinstance(pr.comments[0].created_at, datetime)
|
||||||
|
|
||||||
|
|
||||||
def test_nested_top_hits_are_wrapped_properly(pull_request) -> None:
|
def test_nested_top_hits_are_wrapped_properly(pull_request: Any) -> None:
|
||||||
s = PullRequest.search()
|
s = PullRequest.search()
|
||||||
s.aggs.bucket("comments", "nested", path="comments").metric(
|
s.aggs.bucket("comments", "nested", path="comments").metric(
|
||||||
"hits", "top_hits", size=1
|
"hits", "top_hits", size=1
|
||||||
@@ -216,7 +217,7 @@ def test_nested_top_hits_are_wrapped_properly(pull_request) -> None:
|
|||||||
assert isinstance(r.aggregations.comments.hits.hits[0], Comment)
|
assert isinstance(r.aggregations.comments.hits.hits[0], Comment)
|
||||||
|
|
||||||
|
|
||||||
def test_update_object_field(write_client) -> None:
|
def test_update_object_field(write_client: Any) -> None:
|
||||||
Wiki.init()
|
Wiki.init()
|
||||||
w = Wiki(
|
w = Wiki(
|
||||||
owner=User(name="Honza Kral"),
|
owner=User(name="Honza Kral"),
|
||||||
@@ -236,7 +237,7 @@ def test_update_object_field(write_client) -> None:
|
|||||||
assert w.ranked == {"test1": 0.1, "topic2": 0.2}
|
assert w.ranked == {"test1": 0.1, "topic2": 0.2}
|
||||||
|
|
||||||
|
|
||||||
def test_update_script(write_client) -> None:
|
def test_update_script(write_client: Any) -> None:
|
||||||
Wiki.init()
|
Wiki.init()
|
||||||
w = Wiki(owner=User(name="Honza Kral"), _id="opensearch-py", views=42)
|
w = Wiki(owner=User(name="Honza Kral"), _id="opensearch-py", views=42)
|
||||||
w.save()
|
w.save()
|
||||||
@@ -246,7 +247,7 @@ def test_update_script(write_client) -> None:
|
|||||||
assert w.views == 47
|
assert w.views == 47
|
||||||
|
|
||||||
|
|
||||||
def test_update_retry_on_conflict(write_client) -> None:
|
def test_update_retry_on_conflict(write_client: Any) -> None:
|
||||||
Wiki.init()
|
Wiki.init()
|
||||||
w = Wiki(owner=User(name="Honza Kral"), _id="opensearch-py", views=42)
|
w = Wiki(owner=User(name="Honza Kral"), _id="opensearch-py", views=42)
|
||||||
w.save()
|
w.save()
|
||||||
@@ -260,8 +261,8 @@ def test_update_retry_on_conflict(write_client) -> None:
|
|||||||
assert w.views == 52
|
assert w.views == 52
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("retry_on_conflict", [None, 0])
|
@pytest.mark.parametrize("retry_on_conflict", [None, 0]) # type: ignore
|
||||||
def test_update_conflicting_version(write_client, retry_on_conflict) -> None:
|
def test_update_conflicting_version(write_client: Any, retry_on_conflict: Any) -> None:
|
||||||
Wiki.init()
|
Wiki.init()
|
||||||
w = Wiki(owner=User(name="Honza Kral"), _id="opensearch-py", views=42)
|
w = Wiki(owner=User(name="Honza Kral"), _id="opensearch-py", views=42)
|
||||||
w.save()
|
w.save()
|
||||||
@@ -278,7 +279,7 @@ def test_update_conflicting_version(write_client, retry_on_conflict) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_save_and_update_return_doc_meta(write_client) -> None:
|
def test_save_and_update_return_doc_meta(write_client: Any) -> None:
|
||||||
Wiki.init()
|
Wiki.init()
|
||||||
w = Wiki(owner=User(name="Honza Kral"), _id="opensearch-py", views=42)
|
w = Wiki(owner=User(name="Honza Kral"), _id="opensearch-py", views=42)
|
||||||
resp = w.save(return_doc_meta=True)
|
resp = w.save(return_doc_meta=True)
|
||||||
@@ -302,31 +303,33 @@ def test_save_and_update_return_doc_meta(write_client) -> None:
|
|||||||
assert resp.keys().__contains__("_version")
|
assert resp.keys().__contains__("_version")
|
||||||
|
|
||||||
|
|
||||||
def test_init(write_client) -> None:
|
def test_init(write_client: Any) -> None:
|
||||||
Repository.init(index="test-git")
|
Repository.init(index="test-git")
|
||||||
|
|
||||||
assert write_client.indices.exists(index="test-git")
|
assert write_client.indices.exists(index="test-git")
|
||||||
|
|
||||||
|
|
||||||
def test_get_raises_404_on_index_missing(data_client) -> None:
|
def test_get_raises_404_on_index_missing(data_client: Any) -> None:
|
||||||
with raises(NotFoundError):
|
with raises(NotFoundError):
|
||||||
Repository.get("opensearch-dsl-php", index="not-there")
|
Repository.get("opensearch-dsl-php", index="not-there")
|
||||||
|
|
||||||
|
|
||||||
def test_get_raises_404_on_non_existent_id(data_client) -> None:
|
def test_get_raises_404_on_non_existent_id(data_client: Any) -> None:
|
||||||
with raises(NotFoundError):
|
with raises(NotFoundError):
|
||||||
Repository.get("opensearch-dsl-php")
|
Repository.get("opensearch-dsl-php")
|
||||||
|
|
||||||
|
|
||||||
def test_get_returns_none_if_404_ignored(data_client) -> None:
|
def test_get_returns_none_if_404_ignored(data_client: Any) -> None:
|
||||||
assert None is Repository.get("opensearch-dsl-php", ignore=404)
|
assert None is Repository.get("opensearch-dsl-php", ignore=404)
|
||||||
|
|
||||||
|
|
||||||
def test_get_returns_none_if_404_ignored_and_index_doesnt_exist(data_client) -> None:
|
def test_get_returns_none_if_404_ignored_and_index_doesnt_exist(
|
||||||
|
data_client: Any,
|
||||||
|
) -> None:
|
||||||
assert None is Repository.get("42", index="not-there", ignore=404)
|
assert None is Repository.get("42", index="not-there", ignore=404)
|
||||||
|
|
||||||
|
|
||||||
def test_get(data_client) -> None:
|
def test_get(data_client: Any) -> None:
|
||||||
opensearch_repo = Repository.get("opensearch-py")
|
opensearch_repo = Repository.get("opensearch-py")
|
||||||
|
|
||||||
assert isinstance(opensearch_repo, Repository)
|
assert isinstance(opensearch_repo, Repository)
|
||||||
@@ -334,15 +337,15 @@ def test_get(data_client) -> None:
|
|||||||
assert datetime(2014, 3, 3) == opensearch_repo.created_at
|
assert datetime(2014, 3, 3) == opensearch_repo.created_at
|
||||||
|
|
||||||
|
|
||||||
def test_exists_return_true(data_client) -> None:
|
def test_exists_return_true(data_client: Any) -> None:
|
||||||
assert Repository.exists("opensearch-py")
|
assert Repository.exists("opensearch-py")
|
||||||
|
|
||||||
|
|
||||||
def test_exists_false(data_client) -> None:
|
def test_exists_false(data_client: Any) -> None:
|
||||||
assert not Repository.exists("opensearch-dsl-php")
|
assert not Repository.exists("opensearch-dsl-php")
|
||||||
|
|
||||||
|
|
||||||
def test_get_with_tz_date(data_client) -> None:
|
def test_get_with_tz_date(data_client: Any) -> None:
|
||||||
first_commit = Commit.get(
|
first_commit = Commit.get(
|
||||||
id="3ca6e1e73a071a705b4babd2f581c91a2a3e5037", routing="opensearch-py"
|
id="3ca6e1e73a071a705b4babd2f581c91a2a3e5037", routing="opensearch-py"
|
||||||
)
|
)
|
||||||
@@ -354,7 +357,7 @@ def test_get_with_tz_date(data_client) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_save_with_tz_date(data_client) -> None:
|
def test_save_with_tz_date(data_client: Any) -> None:
|
||||||
tzinfo = timezone("Europe/Prague")
|
tzinfo = timezone("Europe/Prague")
|
||||||
first_commit = Commit.get(
|
first_commit = Commit.get(
|
||||||
id="3ca6e1e73a071a705b4babd2f581c91a2a3e5037", routing="opensearch-py"
|
id="3ca6e1e73a071a705b4babd2f581c91a2a3e5037", routing="opensearch-py"
|
||||||
@@ -381,7 +384,7 @@ COMMIT_DOCS_WITH_MISSING = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def test_mget(data_client) -> None:
|
def test_mget(data_client: Any) -> None:
|
||||||
commits = Commit.mget(COMMIT_DOCS_WITH_MISSING)
|
commits = Commit.mget(COMMIT_DOCS_WITH_MISSING)
|
||||||
assert commits[0] is None
|
assert commits[0] is None
|
||||||
assert commits[1].meta.id == "3ca6e1e73a071a705b4babd2f581c91a2a3e5037"
|
assert commits[1].meta.id == "3ca6e1e73a071a705b4babd2f581c91a2a3e5037"
|
||||||
@@ -389,23 +392,23 @@ def test_mget(data_client) -> None:
|
|||||||
assert commits[3].meta.id == "eb3e543323f189fd7b698e66295427204fff5755"
|
assert commits[3].meta.id == "eb3e543323f189fd7b698e66295427204fff5755"
|
||||||
|
|
||||||
|
|
||||||
def test_mget_raises_exception_when_missing_param_is_invalid(data_client) -> None:
|
def test_mget_raises_exception_when_missing_param_is_invalid(data_client: Any) -> None:
|
||||||
with raises(ValueError):
|
with raises(ValueError):
|
||||||
Commit.mget(COMMIT_DOCS_WITH_MISSING, missing="raj")
|
Commit.mget(COMMIT_DOCS_WITH_MISSING, missing="raj")
|
||||||
|
|
||||||
|
|
||||||
def test_mget_raises_404_when_missing_param_is_raise(data_client) -> None:
|
def test_mget_raises_404_when_missing_param_is_raise(data_client: Any) -> None:
|
||||||
with raises(NotFoundError):
|
with raises(NotFoundError):
|
||||||
Commit.mget(COMMIT_DOCS_WITH_MISSING, missing="raise")
|
Commit.mget(COMMIT_DOCS_WITH_MISSING, missing="raise")
|
||||||
|
|
||||||
|
|
||||||
def test_mget_ignores_missing_docs_when_missing_param_is_skip(data_client) -> None:
|
def test_mget_ignores_missing_docs_when_missing_param_is_skip(data_client: Any) -> None:
|
||||||
commits = Commit.mget(COMMIT_DOCS_WITH_MISSING, missing="skip")
|
commits = Commit.mget(COMMIT_DOCS_WITH_MISSING, missing="skip")
|
||||||
assert commits[0].meta.id == "3ca6e1e73a071a705b4babd2f581c91a2a3e5037"
|
assert commits[0].meta.id == "3ca6e1e73a071a705b4babd2f581c91a2a3e5037"
|
||||||
assert commits[1].meta.id == "eb3e543323f189fd7b698e66295427204fff5755"
|
assert commits[1].meta.id == "eb3e543323f189fd7b698e66295427204fff5755"
|
||||||
|
|
||||||
|
|
||||||
def test_update_works_from_search_response(data_client) -> None:
|
def test_update_works_from_search_response(data_client: Any) -> None:
|
||||||
opensearch_repo = Repository.search().execute()[0]
|
opensearch_repo = Repository.search().execute()[0]
|
||||||
|
|
||||||
opensearch_repo.update(owner={"other_name": "opensearchpy"})
|
opensearch_repo.update(owner={"other_name": "opensearchpy"})
|
||||||
@@ -416,7 +419,7 @@ def test_update_works_from_search_response(data_client) -> None:
|
|||||||
assert "opensearch" == new_version.owner.name
|
assert "opensearch" == new_version.owner.name
|
||||||
|
|
||||||
|
|
||||||
def test_update(data_client) -> None:
|
def test_update(data_client: Any) -> None:
|
||||||
opensearch_repo = Repository.get("opensearch-py")
|
opensearch_repo = Repository.get("opensearch-py")
|
||||||
v = opensearch_repo.meta.version
|
v = opensearch_repo.meta.version
|
||||||
|
|
||||||
@@ -440,7 +443,7 @@ def test_update(data_client) -> None:
|
|||||||
assert "primary_term" in new_version.meta
|
assert "primary_term" in new_version.meta
|
||||||
|
|
||||||
|
|
||||||
def test_save_updates_existing_doc(data_client) -> None:
|
def test_save_updates_existing_doc(data_client: Any) -> None:
|
||||||
opensearch_repo = Repository.get("opensearch-py")
|
opensearch_repo = Repository.get("opensearch-py")
|
||||||
|
|
||||||
opensearch_repo.new_field = "testing-save"
|
opensearch_repo.new_field = "testing-save"
|
||||||
@@ -453,7 +456,7 @@ def test_save_updates_existing_doc(data_client) -> None:
|
|||||||
assert new_repo["_seq_no"] == opensearch_repo.meta.seq_no
|
assert new_repo["_seq_no"] == opensearch_repo.meta.seq_no
|
||||||
|
|
||||||
|
|
||||||
def test_save_automatically_uses_seq_no_and_primary_term(data_client) -> None:
|
def test_save_automatically_uses_seq_no_and_primary_term(data_client: Any) -> None:
|
||||||
opensearch_repo = Repository.get("opensearch-py")
|
opensearch_repo = Repository.get("opensearch-py")
|
||||||
opensearch_repo.meta.seq_no += 1
|
opensearch_repo.meta.seq_no += 1
|
||||||
|
|
||||||
@@ -461,7 +464,7 @@ def test_save_automatically_uses_seq_no_and_primary_term(data_client) -> None:
|
|||||||
opensearch_repo.save()
|
opensearch_repo.save()
|
||||||
|
|
||||||
|
|
||||||
def test_delete_automatically_uses_seq_no_and_primary_term(data_client) -> None:
|
def test_delete_automatically_uses_seq_no_and_primary_term(data_client: Any) -> None:
|
||||||
opensearch_repo = Repository.get("opensearch-py")
|
opensearch_repo = Repository.get("opensearch-py")
|
||||||
opensearch_repo.meta.seq_no += 1
|
opensearch_repo.meta.seq_no += 1
|
||||||
|
|
||||||
@@ -469,13 +472,13 @@ def test_delete_automatically_uses_seq_no_and_primary_term(data_client) -> None:
|
|||||||
opensearch_repo.delete()
|
opensearch_repo.delete()
|
||||||
|
|
||||||
|
|
||||||
def assert_doc_equals(expected, actual) -> None:
|
def assert_doc_equals(expected: Any, actual: Any) -> None:
|
||||||
for f in expected:
|
for f in expected:
|
||||||
assert f in actual
|
assert f in actual
|
||||||
assert actual[f] == expected[f]
|
assert actual[f] == expected[f]
|
||||||
|
|
||||||
|
|
||||||
def test_can_save_to_different_index(write_client):
|
def test_can_save_to_different_index(write_client: Any) -> None:
|
||||||
test_repo = Repository(description="testing", meta={"id": 42})
|
test_repo = Repository(description="testing", meta={"id": 42})
|
||||||
assert test_repo.save(index="test-document")
|
assert test_repo.save(index="test-document")
|
||||||
|
|
||||||
@@ -490,7 +493,7 @@ def test_can_save_to_different_index(write_client):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_save_without_skip_empty_will_include_empty_fields(write_client) -> None:
|
def test_save_without_skip_empty_will_include_empty_fields(write_client: Any) -> None:
|
||||||
test_repo = Repository(field_1=[], field_2=None, field_3={}, meta={"id": 42})
|
test_repo = Repository(field_1=[], field_2=None, field_3={}, meta={"id": 42})
|
||||||
assert test_repo.save(index="test-document", skip_empty=False)
|
assert test_repo.save(index="test-document", skip_empty=False)
|
||||||
|
|
||||||
@@ -505,7 +508,7 @@ def test_save_without_skip_empty_will_include_empty_fields(write_client) -> None
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_delete(write_client) -> None:
|
def test_delete(write_client: Any) -> None:
|
||||||
write_client.create(
|
write_client.create(
|
||||||
index="test-document",
|
index="test-document",
|
||||||
id="opensearch-py",
|
id="opensearch-py",
|
||||||
@@ -526,11 +529,11 @@ def test_delete(write_client) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_search(data_client) -> None:
|
def test_search(data_client: Any) -> None:
|
||||||
assert Repository.search().count() == 1
|
assert Repository.search().count() == 1
|
||||||
|
|
||||||
|
|
||||||
def test_search_returns_proper_doc_classes(data_client) -> None:
|
def test_search_returns_proper_doc_classes(data_client: Any) -> None:
|
||||||
result = Repository.search().execute()
|
result = Repository.search().execute()
|
||||||
|
|
||||||
opensearch_repo = result.hits[0]
|
opensearch_repo = result.hits[0]
|
||||||
@@ -539,11 +542,13 @@ def test_search_returns_proper_doc_classes(data_client) -> None:
|
|||||||
assert opensearch_repo.owner.name == "opensearch"
|
assert opensearch_repo.owner.name == "opensearch"
|
||||||
|
|
||||||
|
|
||||||
def test_refresh_mapping(data_client) -> None:
|
def test_refresh_mapping(data_client: Any) -> None:
|
||||||
class Commit(Document):
|
class Commit(Document):
|
||||||
class Index:
|
class Index:
|
||||||
name = "git"
|
name = "git"
|
||||||
|
|
||||||
|
_index: Any
|
||||||
|
|
||||||
Commit._index.load_mappings()
|
Commit._index.load_mappings()
|
||||||
|
|
||||||
assert "stats" in Commit._index._mapping
|
assert "stats" in Commit._index._mapping
|
||||||
@@ -553,7 +558,7 @@ def test_refresh_mapping(data_client) -> None:
|
|||||||
assert isinstance(Commit._index._mapping["committed_date"], Date)
|
assert isinstance(Commit._index._mapping["committed_date"], Date)
|
||||||
|
|
||||||
|
|
||||||
def test_highlight_in_meta(data_client) -> None:
|
def test_highlight_in_meta(data_client: Any) -> None:
|
||||||
commit = (
|
commit = (
|
||||||
Commit.search()
|
Commit.search()
|
||||||
.query("match", description="inverting")
|
.query("match", description="inverting")
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@@ -66,8 +67,8 @@ class MetricSearch(FacetedSearch):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session") # type: ignore
|
||||||
def commit_search_cls(opensearch_version):
|
def commit_search_cls(opensearch_version: Any) -> Any:
|
||||||
interval_kwargs = {"fixed_interval": "1d"}
|
interval_kwargs = {"fixed_interval": "1d"}
|
||||||
|
|
||||||
class CommitSearch(FacetedSearch):
|
class CommitSearch(FacetedSearch):
|
||||||
@@ -91,8 +92,8 @@ def commit_search_cls(opensearch_version):
|
|||||||
return CommitSearch
|
return CommitSearch
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session") # type: ignore
|
||||||
def repo_search_cls(opensearch_version):
|
def repo_search_cls(opensearch_version: Any) -> Any:
|
||||||
interval_type = "calendar_interval"
|
interval_type = "calendar_interval"
|
||||||
|
|
||||||
class RepoSearch(FacetedSearch):
|
class RepoSearch(FacetedSearch):
|
||||||
@@ -105,15 +106,15 @@ def repo_search_cls(opensearch_version):
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
def search(self):
|
def search(self) -> Any:
|
||||||
s = super(RepoSearch, self).search()
|
s = super(RepoSearch, self).search()
|
||||||
return s.filter("term", commit_repo="repo")
|
return s.filter("term", commit_repo="repo")
|
||||||
|
|
||||||
return RepoSearch
|
return RepoSearch
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session") # type: ignore
|
||||||
def pr_search_cls(opensearch_version):
|
def pr_search_cls(opensearch_version: Any) -> Any:
|
||||||
interval_type = "calendar_interval"
|
interval_type = "calendar_interval"
|
||||||
|
|
||||||
class PRSearch(FacetedSearch):
|
class PRSearch(FacetedSearch):
|
||||||
@@ -131,7 +132,7 @@ def pr_search_cls(opensearch_version):
|
|||||||
return PRSearch
|
return PRSearch
|
||||||
|
|
||||||
|
|
||||||
def test_facet_with_custom_metric(data_client) -> None:
|
def test_facet_with_custom_metric(data_client: Any) -> None:
|
||||||
ms = MetricSearch()
|
ms = MetricSearch()
|
||||||
r = ms.execute()
|
r = ms.execute()
|
||||||
|
|
||||||
@@ -140,7 +141,7 @@ def test_facet_with_custom_metric(data_client) -> None:
|
|||||||
assert dates[0] == 1399038439000
|
assert dates[0] == 1399038439000
|
||||||
|
|
||||||
|
|
||||||
def test_nested_facet(pull_request, pr_search_cls) -> None:
|
def test_nested_facet(pull_request: Any, pr_search_cls: Any) -> None:
|
||||||
prs = pr_search_cls()
|
prs = pr_search_cls()
|
||||||
r = prs.execute()
|
r = prs.execute()
|
||||||
|
|
||||||
@@ -148,7 +149,7 @@ def test_nested_facet(pull_request, pr_search_cls) -> None:
|
|||||||
assert [(datetime(2018, 1, 1, 0, 0), 1, False)] == r.facets.comments
|
assert [(datetime(2018, 1, 1, 0, 0), 1, False)] == r.facets.comments
|
||||||
|
|
||||||
|
|
||||||
def test_nested_facet_with_filter(pull_request, pr_search_cls) -> None:
|
def test_nested_facet_with_filter(pull_request: Any, pr_search_cls: Any) -> None:
|
||||||
prs = pr_search_cls(filters={"comments": datetime(2018, 1, 1, 0, 0)})
|
prs = pr_search_cls(filters={"comments": datetime(2018, 1, 1, 0, 0)})
|
||||||
r = prs.execute()
|
r = prs.execute()
|
||||||
|
|
||||||
@@ -160,7 +161,7 @@ def test_nested_facet_with_filter(pull_request, pr_search_cls) -> None:
|
|||||||
assert not r.hits
|
assert not r.hits
|
||||||
|
|
||||||
|
|
||||||
def test_datehistogram_facet(data_client, repo_search_cls) -> None:
|
def test_datehistogram_facet(data_client: Any, repo_search_cls: Any) -> None:
|
||||||
rs = repo_search_cls()
|
rs = repo_search_cls()
|
||||||
r = rs.execute()
|
r = rs.execute()
|
||||||
|
|
||||||
@@ -168,7 +169,7 @@ def test_datehistogram_facet(data_client, repo_search_cls) -> None:
|
|||||||
assert [(datetime(2014, 3, 1, 0, 0), 1, False)] == r.facets.created
|
assert [(datetime(2014, 3, 1, 0, 0), 1, False)] == r.facets.created
|
||||||
|
|
||||||
|
|
||||||
def test_boolean_facet(data_client, repo_search_cls) -> None:
|
def test_boolean_facet(data_client: Any, repo_search_cls: Any) -> None:
|
||||||
rs = repo_search_cls()
|
rs = repo_search_cls()
|
||||||
r = rs.execute()
|
r = rs.execute()
|
||||||
|
|
||||||
@@ -179,7 +180,7 @@ def test_boolean_facet(data_client, repo_search_cls) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_empty_search_finds_everything(
|
def test_empty_search_finds_everything(
|
||||||
data_client, opensearch_version, commit_search_cls
|
data_client: Any, opensearch_version: Any, commit_search_cls: Any
|
||||||
) -> None:
|
) -> None:
|
||||||
cs = commit_search_cls()
|
cs = commit_search_cls()
|
||||||
r = cs.execute()
|
r = cs.execute()
|
||||||
@@ -225,7 +226,7 @@ def test_empty_search_finds_everything(
|
|||||||
|
|
||||||
|
|
||||||
def test_term_filters_are_shown_as_selected_and_data_is_filtered(
|
def test_term_filters_are_shown_as_selected_and_data_is_filtered(
|
||||||
data_client, commit_search_cls
|
data_client: Any, commit_search_cls: Any
|
||||||
) -> None:
|
) -> None:
|
||||||
cs = commit_search_cls(filters={"files": "test_opensearchpy/test_dsl"})
|
cs = commit_search_cls(filters={"files": "test_opensearchpy/test_dsl"})
|
||||||
|
|
||||||
@@ -271,7 +272,7 @@ def test_term_filters_are_shown_as_selected_and_data_is_filtered(
|
|||||||
|
|
||||||
|
|
||||||
def test_range_filters_are_shown_as_selected_and_data_is_filtered(
|
def test_range_filters_are_shown_as_selected_and_data_is_filtered(
|
||||||
data_client, commit_search_cls
|
data_client: Any, commit_search_cls: Any
|
||||||
) -> None:
|
) -> None:
|
||||||
cs = commit_search_cls(filters={"deletions": "better"})
|
cs = commit_search_cls(filters={"deletions": "better"})
|
||||||
|
|
||||||
@@ -280,7 +281,7 @@ def test_range_filters_are_shown_as_selected_and_data_is_filtered(
|
|||||||
assert 19 == r.hits.total.value
|
assert 19 == r.hits.total.value
|
||||||
|
|
||||||
|
|
||||||
def test_pagination(data_client, commit_search_cls) -> None:
|
def test_pagination(data_client: Any, commit_search_cls: Any) -> None:
|
||||||
cs = commit_search_cls()
|
cs = commit_search_cls()
|
||||||
cs = cs[0:20]
|
cs = cs[0:20]
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,8 @@
|
|||||||
# specific language governing permissions and limitations
|
# specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from opensearchpy import Date, Document, Index, IndexTemplate, Text
|
from opensearchpy import Date, Document, Index, IndexTemplate, Text
|
||||||
from opensearchpy.helpers import analysis
|
from opensearchpy.helpers import analysis
|
||||||
|
|
||||||
@@ -34,7 +36,7 @@ class Post(Document):
|
|||||||
published_from = Date()
|
published_from = Date()
|
||||||
|
|
||||||
|
|
||||||
def test_index_template_works(write_client) -> None:
|
def test_index_template_works(write_client: Any) -> None:
|
||||||
it = IndexTemplate("test-template", "test-*")
|
it = IndexTemplate("test-template", "test-*")
|
||||||
it.document(Post)
|
it.document(Post)
|
||||||
it.settings(number_of_replicas=0, number_of_shards=1)
|
it.settings(number_of_replicas=0, number_of_shards=1)
|
||||||
@@ -55,7 +57,7 @@ def test_index_template_works(write_client) -> None:
|
|||||||
} == write_client.indices.get_mapping(index="test-blog")
|
} == write_client.indices.get_mapping(index="test-blog")
|
||||||
|
|
||||||
|
|
||||||
def test_index_can_be_saved_even_with_settings(write_client) -> None:
|
def test_index_can_be_saved_even_with_settings(write_client: Any) -> None:
|
||||||
i = Index("test-blog", using=write_client)
|
i = Index("test-blog", using=write_client)
|
||||||
i.settings(number_of_shards=3, number_of_replicas=0)
|
i.settings(number_of_shards=3, number_of_replicas=0)
|
||||||
i.save()
|
i.save()
|
||||||
@@ -67,12 +69,12 @@ def test_index_can_be_saved_even_with_settings(write_client) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_index_exists(data_client) -> None:
|
def test_index_exists(data_client: Any) -> None:
|
||||||
assert Index("git").exists()
|
assert Index("git").exists()
|
||||||
assert not Index("not-there").exists()
|
assert not Index("not-there").exists()
|
||||||
|
|
||||||
|
|
||||||
def test_index_can_be_created_with_settings_and_mappings(write_client) -> None:
|
def test_index_can_be_created_with_settings_and_mappings(write_client: Any) -> None:
|
||||||
i = Index("test-blog", using=write_client)
|
i = Index("test-blog", using=write_client)
|
||||||
i.document(Post)
|
i.document(Post)
|
||||||
i.settings(number_of_replicas=0, number_of_shards=1)
|
i.settings(number_of_replicas=0, number_of_shards=1)
|
||||||
@@ -97,7 +99,7 @@ def test_index_can_be_created_with_settings_and_mappings(write_client) -> None:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_delete(write_client) -> None:
|
def test_delete(write_client: Any) -> None:
|
||||||
write_client.indices.create(
|
write_client.indices.create(
|
||||||
index="test-index",
|
index="test-index",
|
||||||
body={"settings": {"number_of_replicas": 0, "number_of_shards": 1}},
|
body={"settings": {"number_of_replicas": 0, "number_of_shards": 1}},
|
||||||
@@ -108,7 +110,7 @@ def test_delete(write_client) -> None:
|
|||||||
assert not write_client.indices.exists(index="test-index")
|
assert not write_client.indices.exists(index="test-index")
|
||||||
|
|
||||||
|
|
||||||
def test_multiple_indices_with_same_doc_type_work(write_client) -> None:
|
def test_multiple_indices_with_same_doc_type_work(write_client: Any) -> None:
|
||||||
i1 = Index("test-index-1", using=write_client)
|
i1 = Index("test-index-1", using=write_client)
|
||||||
i2 = Index("test-index-2", using=write_client)
|
i2 = Index("test-index-2", using=write_client)
|
||||||
|
|
||||||
@@ -116,8 +118,8 @@ def test_multiple_indices_with_same_doc_type_work(write_client) -> None:
|
|||||||
i.document(Post)
|
i.document(Post)
|
||||||
i.create()
|
i.create()
|
||||||
|
|
||||||
for i in ("test-index-1", "test-index-2"):
|
for j in ("test-index-1", "test-index-2"):
|
||||||
settings = write_client.indices.get_settings(index=i)
|
settings = write_client.indices.get_settings(index=j)
|
||||||
assert settings[i]["settings"]["index"]["analysis"] == {
|
assert settings[j]["settings"]["index"]["analysis"] == {
|
||||||
"analyzer": {"my_analyzer": {"type": "custom", "tokenizer": "keyword"}}
|
"analyzer": {"my_analyzer": {"type": "custom", "tokenizer": "keyword"}}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,13 +25,15 @@
|
|||||||
# specific language governing permissions and limitations
|
# specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from pytest import raises
|
from pytest import raises
|
||||||
|
|
||||||
from opensearchpy import exceptions
|
from opensearchpy import exceptions
|
||||||
from opensearchpy.helpers import analysis, mapping
|
from opensearchpy.helpers import analysis, mapping
|
||||||
|
|
||||||
|
|
||||||
def test_mapping_saved_into_opensearch(write_client) -> None:
|
def test_mapping_saved_into_opensearch(write_client: Any) -> None:
|
||||||
m = mapping.Mapping()
|
m = mapping.Mapping()
|
||||||
m.field(
|
m.field(
|
||||||
"name", "text", analyzer=analysis.analyzer("my_analyzer", tokenizer="keyword")
|
"name", "text", analyzer=analysis.analyzer("my_analyzer", tokenizer="keyword")
|
||||||
@@ -52,7 +54,7 @@ def test_mapping_saved_into_opensearch(write_client) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_mapping_saved_into_opensearch_when_index_already_exists_closed(
|
def test_mapping_saved_into_opensearch_when_index_already_exists_closed(
|
||||||
write_client,
|
write_client: Any,
|
||||||
) -> None:
|
) -> None:
|
||||||
m = mapping.Mapping()
|
m = mapping.Mapping()
|
||||||
m.field(
|
m.field(
|
||||||
@@ -77,7 +79,7 @@ def test_mapping_saved_into_opensearch_when_index_already_exists_closed(
|
|||||||
|
|
||||||
|
|
||||||
def test_mapping_saved_into_opensearch_when_index_already_exists_with_analysis(
|
def test_mapping_saved_into_opensearch_when_index_already_exists_with_analysis(
|
||||||
write_client,
|
write_client: Any,
|
||||||
) -> None:
|
) -> None:
|
||||||
m = mapping.Mapping()
|
m = mapping.Mapping()
|
||||||
analyzer = analysis.analyzer("my_analyzer", tokenizer="keyword")
|
analyzer = analysis.analyzer("my_analyzer", tokenizer="keyword")
|
||||||
@@ -107,7 +109,7 @@ def test_mapping_saved_into_opensearch_when_index_already_exists_with_analysis(
|
|||||||
} == write_client.indices.get_mapping(index="test-mapping")
|
} == write_client.indices.get_mapping(index="test-mapping")
|
||||||
|
|
||||||
|
|
||||||
def test_mapping_gets_updated_from_opensearch(write_client):
|
def test_mapping_gets_updated_from_opensearch(write_client: Any) -> None:
|
||||||
write_client.indices.create(
|
write_client.indices.create(
|
||||||
index="test-mapping",
|
index="test-mapping",
|
||||||
body={
|
body={
|
||||||
|
|||||||
@@ -27,6 +27,8 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from pytest import raises
|
from pytest import raises
|
||||||
|
|
||||||
from opensearchpy import (
|
from opensearchpy import (
|
||||||
@@ -50,7 +52,7 @@ class Repository(Document):
|
|||||||
tags = Keyword()
|
tags = Keyword()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def search(cls):
|
def search(cls, using: Any = None, index: Any = None) -> Any:
|
||||||
return super(Repository, cls).search().filter("term", commit_repo="repo")
|
return super(Repository, cls).search().filter("term", commit_repo="repo")
|
||||||
|
|
||||||
class Index:
|
class Index:
|
||||||
@@ -62,7 +64,7 @@ class Commit(Document):
|
|||||||
name = "flat-git"
|
name = "flat-git"
|
||||||
|
|
||||||
|
|
||||||
def test_filters_aggregation_buckets_are_accessible(data_client) -> None:
|
def test_filters_aggregation_buckets_are_accessible(data_client: Any) -> None:
|
||||||
has_tests_query = Q("term", files="test_opensearchpy/test_dsl")
|
has_tests_query = Q("term", files="test_opensearchpy/test_dsl")
|
||||||
s = Commit.search()[0:0]
|
s = Commit.search()[0:0]
|
||||||
s.aggs.bucket("top_authors", "terms", field="author.name.raw").bucket(
|
s.aggs.bucket("top_authors", "terms", field="author.name.raw").bucket(
|
||||||
@@ -83,7 +85,7 @@ def test_filters_aggregation_buckets_are_accessible(data_client) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_top_hits_are_wrapped_in_response(data_client) -> None:
|
def test_top_hits_are_wrapped_in_response(data_client: Any) -> None:
|
||||||
s = Commit.search()[0:0]
|
s = Commit.search()[0:0]
|
||||||
s.aggs.bucket("top_authors", "terms", field="author.name.raw").metric(
|
s.aggs.bucket("top_authors", "terms", field="author.name.raw").metric(
|
||||||
"top_commits", "top_hits", size=5
|
"top_commits", "top_hits", size=5
|
||||||
@@ -99,7 +101,7 @@ def test_top_hits_are_wrapped_in_response(data_client) -> None:
|
|||||||
assert isinstance(hits[0], Commit)
|
assert isinstance(hits[0], Commit)
|
||||||
|
|
||||||
|
|
||||||
def test_inner_hits_are_wrapped_in_response(data_client) -> None:
|
def test_inner_hits_are_wrapped_in_response(data_client: Any) -> None:
|
||||||
s = Search(index="git")[0:1].query(
|
s = Search(index="git")[0:1].query(
|
||||||
"has_parent", parent_type="repo", inner_hits={}, query=Q("match_all")
|
"has_parent", parent_type="repo", inner_hits={}, query=Q("match_all")
|
||||||
)
|
)
|
||||||
@@ -110,7 +112,7 @@ def test_inner_hits_are_wrapped_in_response(data_client) -> None:
|
|||||||
assert repr(commit.meta.inner_hits.repo[0]).startswith("<Hit(git/opensearch-py): ")
|
assert repr(commit.meta.inner_hits.repo[0]).startswith("<Hit(git/opensearch-py): ")
|
||||||
|
|
||||||
|
|
||||||
def test_scan_respects_doc_types(data_client) -> None:
|
def test_scan_respects_doc_types(data_client: Any) -> None:
|
||||||
repos = list(Repository.search().scan())
|
repos = list(Repository.search().scan())
|
||||||
|
|
||||||
assert 1 == len(repos)
|
assert 1 == len(repos)
|
||||||
@@ -118,7 +120,7 @@ def test_scan_respects_doc_types(data_client) -> None:
|
|||||||
assert repos[0].organization == "opensearch"
|
assert repos[0].organization == "opensearch"
|
||||||
|
|
||||||
|
|
||||||
def test_scan_iterates_through_all_docs(data_client) -> None:
|
def test_scan_iterates_through_all_docs(data_client: Any) -> None:
|
||||||
s = Search(index="flat-git")
|
s = Search(index="flat-git")
|
||||||
|
|
||||||
commits = list(s.scan())
|
commits = list(s.scan())
|
||||||
@@ -127,7 +129,7 @@ def test_scan_iterates_through_all_docs(data_client) -> None:
|
|||||||
assert {d["_id"] for d in FLAT_DATA} == {c.meta.id for c in commits}
|
assert {d["_id"] for d in FLAT_DATA} == {c.meta.id for c in commits}
|
||||||
|
|
||||||
|
|
||||||
def test_response_is_cached(data_client) -> None:
|
def test_response_is_cached(data_client: Any) -> None:
|
||||||
s = Repository.search()
|
s = Repository.search()
|
||||||
repos = list(s)
|
repos = list(s)
|
||||||
|
|
||||||
@@ -135,7 +137,7 @@ def test_response_is_cached(data_client) -> None:
|
|||||||
assert s._response.hits == repos
|
assert s._response.hits == repos
|
||||||
|
|
||||||
|
|
||||||
def test_multi_search(data_client) -> None:
|
def test_multi_search(data_client: Any) -> None:
|
||||||
s1 = Repository.search()
|
s1 = Repository.search()
|
||||||
s2 = Search(index="flat-git")
|
s2 = Search(index="flat-git")
|
||||||
|
|
||||||
@@ -152,7 +154,7 @@ def test_multi_search(data_client) -> None:
|
|||||||
assert r2._search is s2
|
assert r2._search is s2
|
||||||
|
|
||||||
|
|
||||||
def test_multi_missing(data_client) -> None:
|
def test_multi_missing(data_client: Any) -> None:
|
||||||
s1 = Repository.search()
|
s1 = Repository.search()
|
||||||
s2 = Search(index="flat-git")
|
s2 = Search(index="flat-git")
|
||||||
s3 = Search(index="does_not_exist")
|
s3 = Search(index="does_not_exist")
|
||||||
@@ -175,7 +177,7 @@ def test_multi_missing(data_client) -> None:
|
|||||||
assert r3 is None
|
assert r3 is None
|
||||||
|
|
||||||
|
|
||||||
def test_raw_subfield_can_be_used_in_aggs(data_client) -> None:
|
def test_raw_subfield_can_be_used_in_aggs(data_client: Any) -> None:
|
||||||
s = Search(index="git")[0:0]
|
s = Search(index="git")[0:0]
|
||||||
s.aggs.bucket("authors", "terms", field="author.name.raw", size=1)
|
s.aggs.bucket("authors", "terms", field="author.name.raw", size=1)
|
||||||
|
|
||||||
|
|||||||
@@ -25,11 +25,13 @@
|
|||||||
# specific language governing permissions and limitations
|
# specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from opensearchpy.helpers.search import Q
|
from opensearchpy.helpers.search import Q
|
||||||
from opensearchpy.helpers.update_by_query import UpdateByQuery
|
from opensearchpy.helpers.update_by_query import UpdateByQuery
|
||||||
|
|
||||||
|
|
||||||
def test_update_by_query_no_script(write_client, setup_ubq_tests) -> None:
|
def test_update_by_query_no_script(write_client: Any, setup_ubq_tests: Any) -> None:
|
||||||
index = setup_ubq_tests
|
index = setup_ubq_tests
|
||||||
|
|
||||||
ubq = (
|
ubq = (
|
||||||
@@ -48,7 +50,7 @@ def test_update_by_query_no_script(write_client, setup_ubq_tests) -> None:
|
|||||||
assert response.success()
|
assert response.success()
|
||||||
|
|
||||||
|
|
||||||
def test_update_by_query_with_script(write_client, setup_ubq_tests) -> None:
|
def test_update_by_query_with_script(write_client: Any, setup_ubq_tests: Any) -> None:
|
||||||
index = setup_ubq_tests
|
index = setup_ubq_tests
|
||||||
|
|
||||||
ubq = (
|
ubq = (
|
||||||
@@ -65,7 +67,7 @@ def test_update_by_query_with_script(write_client, setup_ubq_tests) -> None:
|
|||||||
assert response.version_conflicts == 0
|
assert response.version_conflicts == 0
|
||||||
|
|
||||||
|
|
||||||
def test_delete_by_query_with_script(write_client, setup_ubq_tests) -> None:
|
def test_delete_by_query_with_script(write_client: Any, setup_ubq_tests: Any) -> None:
|
||||||
index = setup_ubq_tests
|
index = setup_ubq_tests
|
||||||
|
|
||||||
ubq = (
|
ubq = (
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ class TestAlertingPlugin(OpenSearchTestCase):
|
|||||||
(OPENSEARCH_VERSION) and (OPENSEARCH_VERSION < (2, 0, 0)),
|
(OPENSEARCH_VERSION) and (OPENSEARCH_VERSION < (2, 0, 0)),
|
||||||
"Plugin not supported for opensearch version",
|
"Plugin not supported for opensearch version",
|
||||||
)
|
)
|
||||||
def test_create_destination(self):
|
def test_create_destination(self) -> None:
|
||||||
# Test to create alert destination
|
# Test to create alert destination
|
||||||
dummy_destination = {
|
dummy_destination = {
|
||||||
"name": "my-destination",
|
"name": "my-destination",
|
||||||
@@ -54,7 +54,7 @@ class TestAlertingPlugin(OpenSearchTestCase):
|
|||||||
(OPENSEARCH_VERSION) and (OPENSEARCH_VERSION < (2, 0, 0)),
|
(OPENSEARCH_VERSION) and (OPENSEARCH_VERSION < (2, 0, 0)),
|
||||||
"Plugin not supported for opensearch version",
|
"Plugin not supported for opensearch version",
|
||||||
)
|
)
|
||||||
def test_create_monitor(self):
|
def test_create_monitor(self) -> None:
|
||||||
# Create a dummy destination
|
# Create a dummy destination
|
||||||
self.test_create_destination()
|
self.test_create_destination()
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import os
|
|||||||
import re
|
import re
|
||||||
import warnings
|
import warnings
|
||||||
import zipfile
|
import zipfile
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
import urllib3
|
import urllib3
|
||||||
@@ -142,23 +143,23 @@ FALSEY_VALUES = ("", None, False, 0, 0.0)
|
|||||||
|
|
||||||
|
|
||||||
class YamlRunner:
|
class YamlRunner:
|
||||||
def __init__(self, client) -> None:
|
def __init__(self, client: Any) -> None:
|
||||||
self.client = client
|
self.client = client
|
||||||
self.last_response = None
|
self.last_response: Any = None
|
||||||
|
|
||||||
self._run_code = None
|
self._run_code: Any = None
|
||||||
self._setup_code = None
|
self._setup_code: Any = None
|
||||||
self._teardown_code = None
|
self._teardown_code: Any = None
|
||||||
self._state = {}
|
self._state: Any = {}
|
||||||
|
|
||||||
def use_spec(self, test_spec) -> None:
|
def use_spec(self, test_spec: Any) -> None:
|
||||||
self._setup_code = test_spec.pop("setup", None)
|
self._setup_code = test_spec.pop("setup", None)
|
||||||
self._run_code = test_spec.pop("run", None)
|
self._run_code = test_spec.pop("run", None)
|
||||||
self._teardown_code = test_spec.pop("teardown", None)
|
self._teardown_code = test_spec.pop("teardown", None)
|
||||||
|
|
||||||
def setup(self):
|
def setup(self) -> Any:
|
||||||
# Pull skips from individual tests to not do unnecessary setup.
|
# Pull skips from individual tests to not do unnecessary setup.
|
||||||
skip_code = []
|
skip_code: Any = []
|
||||||
for action in self._run_code:
|
for action in self._run_code:
|
||||||
assert len(action) == 1
|
assert len(action) == 1
|
||||||
action_type, _ = list(action.items())[0]
|
action_type, _ = list(action.items())[0]
|
||||||
@@ -174,12 +175,12 @@ class YamlRunner:
|
|||||||
if self._setup_code:
|
if self._setup_code:
|
||||||
self.run_code(self._setup_code)
|
self.run_code(self._setup_code)
|
||||||
|
|
||||||
def teardown(self) -> None:
|
def teardown(self) -> Any:
|
||||||
if self._teardown_code:
|
if self._teardown_code:
|
||||||
self.section("teardown")
|
self.section("teardown")
|
||||||
self.run_code(self._teardown_code)
|
self.run_code(self._teardown_code)
|
||||||
|
|
||||||
def opensearch_version(self):
|
def opensearch_version(self) -> Any:
|
||||||
global OPENSEARCH_VERSION
|
global OPENSEARCH_VERSION
|
||||||
if OPENSEARCH_VERSION is None:
|
if OPENSEARCH_VERSION is None:
|
||||||
version_string = (self.client.info())["version"]["number"]
|
version_string = (self.client.info())["version"]["number"]
|
||||||
@@ -189,10 +190,10 @@ class YamlRunner:
|
|||||||
OPENSEARCH_VERSION = tuple(int(v) if v.isdigit() else 99 for v in version)
|
OPENSEARCH_VERSION = tuple(int(v) if v.isdigit() else 99 for v in version)
|
||||||
return OPENSEARCH_VERSION
|
return OPENSEARCH_VERSION
|
||||||
|
|
||||||
def section(self, name) -> None:
|
def section(self, name: str) -> None:
|
||||||
print(("=" * 10) + " " + name + " " + ("=" * 10))
|
print(("=" * 10) + " " + name + " " + ("=" * 10))
|
||||||
|
|
||||||
def run(self) -> None:
|
def run(self) -> Any:
|
||||||
try:
|
try:
|
||||||
self.setup()
|
self.setup()
|
||||||
self.section("test")
|
self.section("test")
|
||||||
@@ -203,7 +204,7 @@ class YamlRunner:
|
|||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def run_code(self, test) -> None:
|
def run_code(self, test: Any) -> Any:
|
||||||
"""Execute an instruction based on its type."""
|
"""Execute an instruction based on its type."""
|
||||||
for action in test:
|
for action in test:
|
||||||
assert len(action) == 1
|
assert len(action) == 1
|
||||||
@@ -215,7 +216,7 @@ class YamlRunner:
|
|||||||
else:
|
else:
|
||||||
raise RuntimeError("Invalid action type %r" % (action_type,))
|
raise RuntimeError("Invalid action type %r" % (action_type,))
|
||||||
|
|
||||||
def run_do(self, action) -> None:
|
def run_do(self, action: Any) -> Any:
|
||||||
api = self.client
|
api = self.client
|
||||||
headers = action.pop("headers", None)
|
headers = action.pop("headers", None)
|
||||||
catch = action.pop("catch", None)
|
catch = action.pop("catch", None)
|
||||||
@@ -267,7 +268,7 @@ class YamlRunner:
|
|||||||
|
|
||||||
# Filter out warnings raised by other components.
|
# Filter out warnings raised by other components.
|
||||||
caught_warnings = [
|
caught_warnings = [
|
||||||
str(w.message)
|
str(w.message) # type: ignore
|
||||||
for w in caught_warnings
|
for w in caught_warnings
|
||||||
if w.category == OpenSearchWarning
|
if w.category == OpenSearchWarning
|
||||||
and str(w.message) not in allowed_warnings
|
and str(w.message) not in allowed_warnings
|
||||||
@@ -275,13 +276,13 @@ class YamlRunner:
|
|||||||
|
|
||||||
# Sorting removes the issue with order raised. We only care about
|
# Sorting removes the issue with order raised. We only care about
|
||||||
# if all warnings are raised in the single API call.
|
# if all warnings are raised in the single API call.
|
||||||
if warn and sorted(warn) != sorted(caught_warnings):
|
if warn and sorted(warn) != sorted(caught_warnings): # type: ignore
|
||||||
raise AssertionError(
|
raise AssertionError(
|
||||||
"Expected warnings not equal to actual warnings: expected=%r actual=%r"
|
"Expected warnings not equal to actual warnings: expected=%r actual=%r"
|
||||||
% (warn, caught_warnings)
|
% (warn, caught_warnings)
|
||||||
)
|
)
|
||||||
|
|
||||||
def run_catch(self, catch, exception) -> None:
|
def run_catch(self, catch: Any, exception: Any) -> None:
|
||||||
if catch == "param":
|
if catch == "param":
|
||||||
assert isinstance(exception, TypeError)
|
assert isinstance(exception, TypeError)
|
||||||
return
|
return
|
||||||
@@ -296,7 +297,7 @@ class YamlRunner:
|
|||||||
) is not None
|
) is not None
|
||||||
self.last_response = exception.info
|
self.last_response = exception.info
|
||||||
|
|
||||||
def run_skip(self, skip) -> None:
|
def run_skip(self, skip: Any) -> Any:
|
||||||
global IMPLEMENTED_FEATURES
|
global IMPLEMENTED_FEATURES
|
||||||
|
|
||||||
if "features" in skip:
|
if "features" in skip:
|
||||||
@@ -318,32 +319,32 @@ class YamlRunner:
|
|||||||
if min_version <= (self.opensearch_version()) <= max_version:
|
if min_version <= (self.opensearch_version()) <= max_version:
|
||||||
pytest.skip(reason)
|
pytest.skip(reason)
|
||||||
|
|
||||||
def run_gt(self, action) -> None:
|
def run_gt(self, action: Any) -> None:
|
||||||
for key, value in action.items():
|
for key, value in action.items():
|
||||||
value = self._resolve(value)
|
value = self._resolve(value)
|
||||||
assert self._lookup(key) > value
|
assert self._lookup(key) > value
|
||||||
|
|
||||||
def run_gte(self, action) -> None:
|
def run_gte(self, action: Any) -> None:
|
||||||
for key, value in action.items():
|
for key, value in action.items():
|
||||||
value = self._resolve(value)
|
value = self._resolve(value)
|
||||||
assert self._lookup(key) >= value
|
assert self._lookup(key) >= value
|
||||||
|
|
||||||
def run_lt(self, action) -> None:
|
def run_lt(self, action: Any) -> None:
|
||||||
for key, value in action.items():
|
for key, value in action.items():
|
||||||
value = self._resolve(value)
|
value = self._resolve(value)
|
||||||
assert self._lookup(key) < value
|
assert self._lookup(key) < value
|
||||||
|
|
||||||
def run_lte(self, action) -> None:
|
def run_lte(self, action: Any) -> None:
|
||||||
for key, value in action.items():
|
for key, value in action.items():
|
||||||
value = self._resolve(value)
|
value = self._resolve(value)
|
||||||
assert self._lookup(key) <= value
|
assert self._lookup(key) <= value
|
||||||
|
|
||||||
def run_set(self, action) -> None:
|
def run_set(self, action: Any) -> None:
|
||||||
for key, value in action.items():
|
for key, value in action.items():
|
||||||
value = self._resolve(value)
|
value = self._resolve(value)
|
||||||
self._state[value] = self._lookup(key)
|
self._state[value] = self._lookup(key)
|
||||||
|
|
||||||
def run_is_false(self, action) -> None:
|
def run_is_false(self, action: Any) -> None:
|
||||||
try:
|
try:
|
||||||
value = self._lookup(action)
|
value = self._lookup(action)
|
||||||
except AssertionError:
|
except AssertionError:
|
||||||
@@ -351,23 +352,23 @@ class YamlRunner:
|
|||||||
else:
|
else:
|
||||||
assert value in FALSEY_VALUES
|
assert value in FALSEY_VALUES
|
||||||
|
|
||||||
def run_is_true(self, action) -> None:
|
def run_is_true(self, action: Any) -> None:
|
||||||
value = self._lookup(action)
|
value = self._lookup(action)
|
||||||
assert value not in FALSEY_VALUES
|
assert value not in FALSEY_VALUES
|
||||||
|
|
||||||
def run_length(self, action) -> None:
|
def run_length(self, action: Any) -> None:
|
||||||
for path, expected in action.items():
|
for path, expected in action.items():
|
||||||
value = self._lookup(path)
|
value = self._lookup(path)
|
||||||
expected = self._resolve(expected)
|
expected = self._resolve(expected)
|
||||||
assert expected == len(value)
|
assert expected == len(value)
|
||||||
|
|
||||||
def run_match(self, action) -> None:
|
def run_match(self, action: Any) -> None:
|
||||||
for path, expected in action.items():
|
for path, expected in action.items():
|
||||||
value = self._lookup(path)
|
value = self._lookup(path)
|
||||||
expected = self._resolve(expected)
|
expected = self._resolve(expected)
|
||||||
|
|
||||||
if (
|
if (
|
||||||
isinstance(expected, string_types)
|
isinstance(expected, str)
|
||||||
and expected.startswith("/")
|
and expected.startswith("/")
|
||||||
and expected.endswith("/")
|
and expected.endswith("/")
|
||||||
):
|
):
|
||||||
@@ -379,7 +380,7 @@ class YamlRunner:
|
|||||||
else:
|
else:
|
||||||
self._assert_match_equals(value, expected)
|
self._assert_match_equals(value, expected)
|
||||||
|
|
||||||
def run_contains(self, action) -> None:
|
def run_contains(self, action: Any) -> None:
|
||||||
for path, expected in action.items():
|
for path, expected in action.items():
|
||||||
value = self._lookup(path) # list[dict[str,str]] is returned
|
value = self._lookup(path) # list[dict[str,str]] is returned
|
||||||
expected = self._resolve(expected) # dict[str, str]
|
expected = self._resolve(expected) # dict[str, str]
|
||||||
@@ -387,7 +388,7 @@ class YamlRunner:
|
|||||||
if expected not in value:
|
if expected not in value:
|
||||||
raise AssertionError("%s is not contained by %s" % (expected, value))
|
raise AssertionError("%s is not contained by %s" % (expected, value))
|
||||||
|
|
||||||
def run_transform_and_set(self, action) -> None:
|
def run_transform_and_set(self, action: Any) -> None:
|
||||||
for key, value in action.items():
|
for key, value in action.items():
|
||||||
# Convert #base64EncodeCredentials(id,api_key) to ["id", "api_key"]
|
# Convert #base64EncodeCredentials(id,api_key) to ["id", "api_key"]
|
||||||
if "#base64EncodeCredentials" in value:
|
if "#base64EncodeCredentials" in value:
|
||||||
@@ -397,7 +398,7 @@ class YamlRunner:
|
|||||||
(self._lookup(value[0]), self._lookup(value[1]))
|
(self._lookup(value[0]), self._lookup(value[1]))
|
||||||
)
|
)
|
||||||
|
|
||||||
def _resolve(self, value):
|
def _resolve(self, value: Any) -> Any:
|
||||||
# resolve variables
|
# resolve variables
|
||||||
if isinstance(value, string_types) and "$" in value:
|
if isinstance(value, string_types) and "$" in value:
|
||||||
for k, v in self._state.items():
|
for k, v in self._state.items():
|
||||||
@@ -422,12 +423,13 @@ class YamlRunner:
|
|||||||
value = list(map(self._resolve, value))
|
value = list(map(self._resolve, value))
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def _lookup(self, path):
|
def _lookup(self, path: str) -> Any:
|
||||||
# fetch the possibly nested value from last_response
|
# fetch the possibly nested value from last_response
|
||||||
value = self.last_response
|
value: Any = self.last_response
|
||||||
if path == "$body":
|
if path == "$body":
|
||||||
return value
|
return value
|
||||||
path = path.replace(r"\.", "\1")
|
path = path.replace(r"\.", "\1")
|
||||||
|
step: Any
|
||||||
for step in path.split("."):
|
for step in path.split("."):
|
||||||
if not step:
|
if not step:
|
||||||
continue
|
continue
|
||||||
@@ -449,10 +451,10 @@ class YamlRunner:
|
|||||||
value = value[step]
|
value = value[step]
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def _feature_enabled(self, name) -> bool:
|
def _feature_enabled(self, name: str) -> Any:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _assert_match_equals(self, a, b) -> None:
|
def _assert_match_equals(self, a: Any, b: Any) -> None:
|
||||||
# Handle for large floating points with 'E'
|
# Handle for large floating points with 'E'
|
||||||
if isinstance(b, string_types) and isinstance(a, float) and "e" in repr(a):
|
if isinstance(b, string_types) and isinstance(a, float) and "e" in repr(a):
|
||||||
a = repr(a).replace("e+", "E")
|
a = repr(a).replace("e+", "E")
|
||||||
@@ -460,8 +462,8 @@ class YamlRunner:
|
|||||||
assert a == b, "%r does not match %r" % (a, b)
|
assert a == b, "%r does not match %r" % (a, b)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="function")
|
@pytest.fixture(scope="function") # type: ignore
|
||||||
def sync_runner(sync_client):
|
def sync_runner(sync_client: Any) -> Any:
|
||||||
return YamlRunner(sync_client)
|
return YamlRunner(sync_client)
|
||||||
|
|
||||||
|
|
||||||
@@ -532,8 +534,8 @@ except Exception as e:
|
|||||||
|
|
||||||
if not RUN_ASYNC_REST_API_TESTS:
|
if not RUN_ASYNC_REST_API_TESTS:
|
||||||
|
|
||||||
@pytest.mark.parametrize("test_spec", YAML_TEST_SPECS)
|
@pytest.mark.parametrize("test_spec", YAML_TEST_SPECS) # type: ignore
|
||||||
def test_rest_api_spec(test_spec, sync_runner) -> None:
|
def test_rest_api_spec(test_spec: Any, sync_runner: Any) -> None:
|
||||||
if test_spec.get("skip", False):
|
if test_spec.get("skip", False):
|
||||||
pytest.skip("Manually skipped in 'SKIP_TESTS'")
|
pytest.skip("Manually skipped in 'SKIP_TESTS'")
|
||||||
sync_runner.use_spec(test_spec)
|
sync_runner.use_spec(test_spec)
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ class TestSecurityPlugin(TestCase):
|
|||||||
else:
|
else:
|
||||||
assert False
|
assert False
|
||||||
|
|
||||||
def test_create_user_with_role(self):
|
def test_create_user_with_role(self) -> None:
|
||||||
self.test_create_role()
|
self.test_create_role()
|
||||||
|
|
||||||
# Test to create user
|
# Test to create user
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
import json
|
import json
|
||||||
import time
|
import time
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from mock import patch
|
from mock import patch
|
||||||
|
|
||||||
@@ -42,14 +43,14 @@ from .test_cases import TestCase
|
|||||||
|
|
||||||
|
|
||||||
class DummyConnection(Connection):
|
class DummyConnection(Connection):
|
||||||
def __init__(self, **kwargs) -> None:
|
def __init__(self, **kwargs: Any) -> None:
|
||||||
self.exception = kwargs.pop("exception", None)
|
self.exception = kwargs.pop("exception", None)
|
||||||
self.status, self.data = kwargs.pop("status", 200), kwargs.pop("data", "{}")
|
self.status, self.data = kwargs.pop("status", 200), kwargs.pop("data", "{}")
|
||||||
self.headers = kwargs.pop("headers", {})
|
self.headers = kwargs.pop("headers", {})
|
||||||
self.calls = []
|
self.calls: Any = []
|
||||||
super(DummyConnection, self).__init__(**kwargs)
|
super(DummyConnection, self).__init__(**kwargs)
|
||||||
|
|
||||||
def perform_request(self, *args, **kwargs):
|
def perform_request(self, *args: Any, **kwargs: Any) -> Any:
|
||||||
self.calls.append((args, kwargs))
|
self.calls.append((args, kwargs))
|
||||||
if self.exception:
|
if self.exception:
|
||||||
raise self.exception
|
raise self.exception
|
||||||
@@ -119,20 +120,20 @@ class TestHostsInfoCallback(TestCase):
|
|||||||
chosen = [
|
chosen = [
|
||||||
i
|
i
|
||||||
for i, node_info in enumerate(nodes)
|
for i, node_info in enumerate(nodes)
|
||||||
if get_host_info(node_info, i) is not None
|
if get_host_info(node_info, i) is not None # type: ignore
|
||||||
]
|
]
|
||||||
self.assertEqual([1, 2, 3, 4], chosen)
|
self.assertEqual([1, 2, 3, 4], chosen)
|
||||||
|
|
||||||
|
|
||||||
class TestTransport(TestCase):
|
class TestTransport(TestCase):
|
||||||
def test_single_connection_uses_dummy_connection_pool(self) -> None:
|
def test_single_connection_uses_dummy_connection_pool(self) -> None:
|
||||||
t = Transport([{}])
|
t1: Any = Transport([{}])
|
||||||
self.assertIsInstance(t.connection_pool, DummyConnectionPool)
|
self.assertIsInstance(t1.connection_pool, DummyConnectionPool)
|
||||||
t = Transport([{"host": "localhost"}])
|
t2: Any = Transport([{"host": "localhost"}])
|
||||||
self.assertIsInstance(t.connection_pool, DummyConnectionPool)
|
self.assertIsInstance(t2.connection_pool, DummyConnectionPool)
|
||||||
|
|
||||||
def test_request_timeout_extracted_from_params_and_passed(self) -> None:
|
def test_request_timeout_extracted_from_params_and_passed(self) -> None:
|
||||||
t = Transport([{}], connection_class=DummyConnection)
|
t: Any = Transport([{}], connection_class=DummyConnection)
|
||||||
|
|
||||||
t.perform_request("GET", "/", params={"request_timeout": 42})
|
t.perform_request("GET", "/", params={"request_timeout": 42})
|
||||||
self.assertEqual(1, len(t.get_connection().calls))
|
self.assertEqual(1, len(t.get_connection().calls))
|
||||||
@@ -143,7 +144,7 @@ class TestTransport(TestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def test_timeout_extracted_from_params_and_passed(self) -> None:
|
def test_timeout_extracted_from_params_and_passed(self) -> None:
|
||||||
t = Transport([{}], connection_class=DummyConnection)
|
t: Any = Transport([{}], connection_class=DummyConnection)
|
||||||
|
|
||||||
t.perform_request("GET", "/", params={"timeout": 84})
|
t.perform_request("GET", "/", params={"timeout": 84})
|
||||||
self.assertEqual(1, len(t.get_connection().calls))
|
self.assertEqual(1, len(t.get_connection().calls))
|
||||||
@@ -154,7 +155,7 @@ class TestTransport(TestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def test_opaque_id(self) -> None:
|
def test_opaque_id(self) -> None:
|
||||||
t = Transport([{}], opaque_id="app-1", connection_class=DummyConnection)
|
t: Any = Transport([{}], opaque_id="app-1", connection_class=DummyConnection)
|
||||||
|
|
||||||
t.perform_request("GET", "/")
|
t.perform_request("GET", "/")
|
||||||
self.assertEqual(1, len(t.get_connection().calls))
|
self.assertEqual(1, len(t.get_connection().calls))
|
||||||
@@ -174,7 +175,7 @@ class TestTransport(TestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def test_request_with_custom_user_agent_header(self) -> None:
|
def test_request_with_custom_user_agent_header(self) -> None:
|
||||||
t = Transport([{}], connection_class=DummyConnection)
|
t: Any = Transport([{}], connection_class=DummyConnection)
|
||||||
|
|
||||||
t.perform_request("GET", "/", headers={"user-agent": "my-custom-value/1.2.3"})
|
t.perform_request("GET", "/", headers={"user-agent": "my-custom-value/1.2.3"})
|
||||||
self.assertEqual(1, len(t.get_connection().calls))
|
self.assertEqual(1, len(t.get_connection().calls))
|
||||||
@@ -188,7 +189,9 @@ class TestTransport(TestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def test_send_get_body_as_source(self) -> None:
|
def test_send_get_body_as_source(self) -> None:
|
||||||
t = Transport([{}], send_get_body_as="source", connection_class=DummyConnection)
|
t: Any = Transport(
|
||||||
|
[{}], send_get_body_as="source", connection_class=DummyConnection
|
||||||
|
)
|
||||||
|
|
||||||
t.perform_request("GET", "/", body={})
|
t.perform_request("GET", "/", body={})
|
||||||
self.assertEqual(1, len(t.get_connection().calls))
|
self.assertEqual(1, len(t.get_connection().calls))
|
||||||
@@ -197,14 +200,16 @@ class TestTransport(TestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def test_send_get_body_as_post(self) -> None:
|
def test_send_get_body_as_post(self) -> None:
|
||||||
t = Transport([{}], send_get_body_as="POST", connection_class=DummyConnection)
|
t: Any = Transport(
|
||||||
|
[{}], send_get_body_as="POST", connection_class=DummyConnection
|
||||||
|
)
|
||||||
|
|
||||||
t.perform_request("GET", "/", body={})
|
t.perform_request("GET", "/", body={})
|
||||||
self.assertEqual(1, len(t.get_connection().calls))
|
self.assertEqual(1, len(t.get_connection().calls))
|
||||||
self.assertEqual(("POST", "/", None, b"{}"), t.get_connection().calls[0][0])
|
self.assertEqual(("POST", "/", None, b"{}"), t.get_connection().calls[0][0])
|
||||||
|
|
||||||
def test_body_gets_encoded_into_bytes(self) -> None:
|
def test_body_gets_encoded_into_bytes(self) -> None:
|
||||||
t = Transport([{}], connection_class=DummyConnection)
|
t: Any = Transport([{}], connection_class=DummyConnection)
|
||||||
|
|
||||||
t.perform_request("GET", "/", body="你好")
|
t.perform_request("GET", "/", body="你好")
|
||||||
self.assertEqual(1, len(t.get_connection().calls))
|
self.assertEqual(1, len(t.get_connection().calls))
|
||||||
@@ -214,7 +219,7 @@ class TestTransport(TestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def test_body_bytes_get_passed_untouched(self) -> None:
|
def test_body_bytes_get_passed_untouched(self) -> None:
|
||||||
t = Transport([{}], connection_class=DummyConnection)
|
t: Any = Transport([{}], connection_class=DummyConnection)
|
||||||
|
|
||||||
body = b"\xe4\xbd\xa0\xe5\xa5\xbd"
|
body = b"\xe4\xbd\xa0\xe5\xa5\xbd"
|
||||||
t.perform_request("GET", "/", body=body)
|
t.perform_request("GET", "/", body=body)
|
||||||
@@ -222,7 +227,7 @@ class TestTransport(TestCase):
|
|||||||
self.assertEqual(("GET", "/", None, body), t.get_connection().calls[0][0])
|
self.assertEqual(("GET", "/", None, body), t.get_connection().calls[0][0])
|
||||||
|
|
||||||
def test_body_surrogates_replaced_encoded_into_bytes(self) -> None:
|
def test_body_surrogates_replaced_encoded_into_bytes(self) -> None:
|
||||||
t = Transport([{}], connection_class=DummyConnection)
|
t: Any = Transport([{}], connection_class=DummyConnection)
|
||||||
|
|
||||||
t.perform_request("GET", "/", body="你好\uda6a")
|
t.perform_request("GET", "/", body="你好\uda6a")
|
||||||
self.assertEqual(1, len(t.get_connection().calls))
|
self.assertEqual(1, len(t.get_connection().calls))
|
||||||
@@ -232,26 +237,26 @@ class TestTransport(TestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def test_kwargs_passed_on_to_connections(self) -> None:
|
def test_kwargs_passed_on_to_connections(self) -> None:
|
||||||
t = Transport([{"host": "google.com"}], port=123)
|
t: Any = Transport([{"host": "google.com"}], port=123)
|
||||||
self.assertEqual(1, len(t.connection_pool.connections))
|
self.assertEqual(1, len(t.connection_pool.connections))
|
||||||
self.assertEqual("http://google.com:123", t.connection_pool.connections[0].host)
|
self.assertEqual("http://google.com:123", t.connection_pool.connections[0].host)
|
||||||
|
|
||||||
def test_kwargs_passed_on_to_connection_pool(self) -> None:
|
def test_kwargs_passed_on_to_connection_pool(self) -> None:
|
||||||
dt = object()
|
dt = object()
|
||||||
t = Transport([{}, {}], dead_timeout=dt)
|
t: Any = Transport([{}, {}], dead_timeout=dt)
|
||||||
self.assertIs(dt, t.connection_pool.dead_timeout)
|
self.assertIs(dt, t.connection_pool.dead_timeout)
|
||||||
|
|
||||||
def test_custom_connection_class(self) -> None:
|
def test_custom_connection_class(self) -> None:
|
||||||
class MyConnection(object):
|
class MyConnection(Connection):
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs: Any) -> None:
|
||||||
self.kwargs = kwargs
|
self.kwargs = kwargs
|
||||||
|
|
||||||
t = Transport([{}], connection_class=MyConnection)
|
t: Any = Transport([{}], connection_class=MyConnection)
|
||||||
self.assertEqual(1, len(t.connection_pool.connections))
|
self.assertEqual(1, len(t.connection_pool.connections))
|
||||||
self.assertIsInstance(t.connection_pool.connections[0], MyConnection)
|
self.assertIsInstance(t.connection_pool.connections[0], MyConnection)
|
||||||
|
|
||||||
def test_add_connection(self) -> None:
|
def test_add_connection(self) -> None:
|
||||||
t = Transport([{}], randomize_hosts=False)
|
t: Any = Transport([{}], randomize_hosts=False)
|
||||||
t.add_connection({"host": "google.com", "port": 1234})
|
t.add_connection({"host": "google.com", "port": 1234})
|
||||||
|
|
||||||
self.assertEqual(2, len(t.connection_pool.connections))
|
self.assertEqual(2, len(t.connection_pool.connections))
|
||||||
@@ -260,7 +265,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 = Transport(
|
t: Any = Transport(
|
||||||
[{"exception": ConnectionError("abandon ship")}],
|
[{"exception": ConnectionError("abandon ship")}],
|
||||||
connection_class=DummyConnection,
|
connection_class=DummyConnection,
|
||||||
)
|
)
|
||||||
@@ -269,7 +274,7 @@ class TestTransport(TestCase):
|
|||||||
self.assertEqual(4, len(t.get_connection().calls))
|
self.assertEqual(4, len(t.get_connection().calls))
|
||||||
|
|
||||||
def test_failed_connection_will_be_marked_as_dead(self) -> None:
|
def test_failed_connection_will_be_marked_as_dead(self) -> None:
|
||||||
t = Transport(
|
t: Any = Transport(
|
||||||
[{"exception": ConnectionError("abandon ship")}] * 2,
|
[{"exception": ConnectionError("abandon ship")}] * 2,
|
||||||
connection_class=DummyConnection,
|
connection_class=DummyConnection,
|
||||||
)
|
)
|
||||||
@@ -279,7 +284,7 @@ class TestTransport(TestCase):
|
|||||||
|
|
||||||
def test_resurrected_connection_will_be_marked_as_live_on_success(self) -> None:
|
def test_resurrected_connection_will_be_marked_as_live_on_success(self) -> None:
|
||||||
for method in ("GET", "HEAD"):
|
for method in ("GET", "HEAD"):
|
||||||
t = Transport([{}, {}], connection_class=DummyConnection)
|
t: Any = Transport([{}, {}], connection_class=DummyConnection)
|
||||||
con1 = t.connection_pool.get_connection()
|
con1 = t.connection_pool.get_connection()
|
||||||
con2 = t.connection_pool.get_connection()
|
con2 = t.connection_pool.get_connection()
|
||||||
t.connection_pool.mark_dead(con1)
|
t.connection_pool.mark_dead(con1)
|
||||||
@@ -290,7 +295,7 @@ class TestTransport(TestCase):
|
|||||||
self.assertEqual(1, len(t.connection_pool.dead_count))
|
self.assertEqual(1, len(t.connection_pool.dead_count))
|
||||||
|
|
||||||
def test_sniff_will_use_seed_connections(self) -> None:
|
def test_sniff_will_use_seed_connections(self) -> None:
|
||||||
t = Transport([{"data": CLUSTER_NODES}], connection_class=DummyConnection)
|
t: Any = Transport([{"data": CLUSTER_NODES}], connection_class=DummyConnection)
|
||||||
t.set_connections([{"data": "invalid"}])
|
t.set_connections([{"data": "invalid"}])
|
||||||
|
|
||||||
t.sniff_hosts()
|
t.sniff_hosts()
|
||||||
@@ -298,7 +303,7 @@ class TestTransport(TestCase):
|
|||||||
self.assertEqual("http://1.1.1.1:123", t.get_connection().host)
|
self.assertEqual("http://1.1.1.1:123", t.get_connection().host)
|
||||||
|
|
||||||
def test_sniff_on_start_fetches_and_uses_nodes_list(self) -> None:
|
def test_sniff_on_start_fetches_and_uses_nodes_list(self) -> None:
|
||||||
t = Transport(
|
t: Any = Transport(
|
||||||
[{"data": CLUSTER_NODES}],
|
[{"data": CLUSTER_NODES}],
|
||||||
connection_class=DummyConnection,
|
connection_class=DummyConnection,
|
||||||
sniff_on_start=True,
|
sniff_on_start=True,
|
||||||
@@ -307,7 +312,7 @@ class TestTransport(TestCase):
|
|||||||
self.assertEqual("http://1.1.1.1:123", t.get_connection().host)
|
self.assertEqual("http://1.1.1.1:123", t.get_connection().host)
|
||||||
|
|
||||||
def test_sniff_on_start_ignores_sniff_timeout(self) -> None:
|
def test_sniff_on_start_ignores_sniff_timeout(self) -> None:
|
||||||
t = Transport(
|
t: Any = Transport(
|
||||||
[{"data": CLUSTER_NODES}],
|
[{"data": CLUSTER_NODES}],
|
||||||
connection_class=DummyConnection,
|
connection_class=DummyConnection,
|
||||||
sniff_on_start=True,
|
sniff_on_start=True,
|
||||||
@@ -319,7 +324,7 @@ class TestTransport(TestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def test_sniff_uses_sniff_timeout(self) -> None:
|
def test_sniff_uses_sniff_timeout(self) -> None:
|
||||||
t = Transport(
|
t: Any = Transport(
|
||||||
[{"data": CLUSTER_NODES}],
|
[{"data": CLUSTER_NODES}],
|
||||||
connection_class=DummyConnection,
|
connection_class=DummyConnection,
|
||||||
sniff_timeout=42,
|
sniff_timeout=42,
|
||||||
@@ -330,8 +335,8 @@ class TestTransport(TestCase):
|
|||||||
t.seed_connections[0].calls[0],
|
t.seed_connections[0].calls[0],
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_sniff_reuses_connection_instances_if_possible(self):
|
def test_sniff_reuses_connection_instances_if_possible(self) -> None:
|
||||||
t = Transport(
|
t: Any = Transport(
|
||||||
[{"data": CLUSTER_NODES}, {"host": "1.1.1.1", "port": 123}],
|
[{"data": CLUSTER_NODES}, {"host": "1.1.1.1", "port": 123}],
|
||||||
connection_class=DummyConnection,
|
connection_class=DummyConnection,
|
||||||
randomize_hosts=False,
|
randomize_hosts=False,
|
||||||
@@ -342,8 +347,8 @@ class TestTransport(TestCase):
|
|||||||
self.assertEqual(1, len(t.connection_pool.connections))
|
self.assertEqual(1, len(t.connection_pool.connections))
|
||||||
self.assertIs(connection, t.get_connection())
|
self.assertIs(connection, t.get_connection())
|
||||||
|
|
||||||
def test_sniff_on_fail_triggers_sniffing_on_fail(self):
|
def test_sniff_on_fail_triggers_sniffing_on_fail(self) -> None:
|
||||||
t = Transport(
|
t: Any = Transport(
|
||||||
[{"exception": ConnectionError("abandon ship")}, {"data": CLUSTER_NODES}],
|
[{"exception": ConnectionError("abandon ship")}, {"data": CLUSTER_NODES}],
|
||||||
connection_class=DummyConnection,
|
connection_class=DummyConnection,
|
||||||
sniff_on_connection_fail=True,
|
sniff_on_connection_fail=True,
|
||||||
@@ -356,9 +361,11 @@ class TestTransport(TestCase):
|
|||||||
self.assertEqual("http://1.1.1.1:123", t.get_connection().host)
|
self.assertEqual("http://1.1.1.1:123", t.get_connection().host)
|
||||||
|
|
||||||
@patch("opensearchpy.transport.Transport.sniff_hosts")
|
@patch("opensearchpy.transport.Transport.sniff_hosts")
|
||||||
def test_sniff_on_fail_failing_does_not_prevent_retires(self, sniff_hosts):
|
def test_sniff_on_fail_failing_does_not_prevent_retires(
|
||||||
|
self, sniff_hosts: Any
|
||||||
|
) -> None:
|
||||||
sniff_hosts.side_effect = [TransportError("sniff failed")]
|
sniff_hosts.side_effect = [TransportError("sniff failed")]
|
||||||
t = Transport(
|
t: Any = Transport(
|
||||||
[{"exception": ConnectionError("abandon ship")}, {"data": CLUSTER_NODES}],
|
[{"exception": ConnectionError("abandon ship")}, {"data": CLUSTER_NODES}],
|
||||||
connection_class=DummyConnection,
|
connection_class=DummyConnection,
|
||||||
sniff_on_connection_fail=True,
|
sniff_on_connection_fail=True,
|
||||||
@@ -374,7 +381,7 @@ class TestTransport(TestCase):
|
|||||||
self.assertEqual(1, len(conn_data.calls))
|
self.assertEqual(1, len(conn_data.calls))
|
||||||
|
|
||||||
def test_sniff_after_n_seconds(self) -> None:
|
def test_sniff_after_n_seconds(self) -> None:
|
||||||
t = Transport(
|
t: Any = Transport(
|
||||||
[{"data": CLUSTER_NODES}],
|
[{"data": CLUSTER_NODES}],
|
||||||
connection_class=DummyConnection,
|
connection_class=DummyConnection,
|
||||||
sniffer_timeout=5,
|
sniffer_timeout=5,
|
||||||
@@ -394,7 +401,7 @@ class TestTransport(TestCase):
|
|||||||
def test_sniff_7x_publish_host(self) -> None:
|
def test_sniff_7x_publish_host(self) -> None:
|
||||||
# Test the response shaped when a 7.x node has publish_host set
|
# Test the response shaped when a 7.x node has publish_host set
|
||||||
# and the returend data is shaped in the fqdn/ip:port format.
|
# and the returend data is shaped in the fqdn/ip:port format.
|
||||||
t = Transport(
|
t: Any = Transport(
|
||||||
[{"data": CLUSTER_NODES_7x_PUBLISH_HOST}],
|
[{"data": CLUSTER_NODES_7x_PUBLISH_HOST}],
|
||||||
connection_class=DummyConnection,
|
connection_class=DummyConnection,
|
||||||
sniff_timeout=42,
|
sniff_timeout=42,
|
||||||
|
|||||||
+15
-14
@@ -27,11 +27,12 @@
|
|||||||
|
|
||||||
|
|
||||||
import time
|
import time
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from opensearchpy import OpenSearch
|
from opensearchpy import OpenSearch
|
||||||
|
|
||||||
|
|
||||||
def wipe_cluster(client) -> None:
|
def wipe_cluster(client: Any) -> None:
|
||||||
"""Wipes a cluster clean between test cases"""
|
"""Wipes a cluster clean between test cases"""
|
||||||
close_after_wipe = False
|
close_after_wipe = False
|
||||||
try:
|
try:
|
||||||
@@ -59,9 +60,9 @@ def wipe_cluster(client) -> None:
|
|||||||
client.close()
|
client.close()
|
||||||
|
|
||||||
|
|
||||||
def wipe_cluster_settings(client) -> None:
|
def wipe_cluster_settings(client: Any) -> None:
|
||||||
settings = client.cluster.get_settings()
|
settings = client.cluster.get_settings()
|
||||||
new_settings = {}
|
new_settings: Any = {}
|
||||||
for name, value in settings.items():
|
for name, value in settings.items():
|
||||||
if value:
|
if value:
|
||||||
new_settings.setdefault(name, {})
|
new_settings.setdefault(name, {})
|
||||||
@@ -71,7 +72,7 @@ def wipe_cluster_settings(client) -> None:
|
|||||||
client.cluster.put_settings(body=new_settings)
|
client.cluster.put_settings(body=new_settings)
|
||||||
|
|
||||||
|
|
||||||
def wipe_snapshots(client):
|
def wipe_snapshots(client: Any) -> None:
|
||||||
"""Deletes all the snapshots and repositories from the cluster"""
|
"""Deletes all the snapshots and repositories from the cluster"""
|
||||||
in_progress_snapshots = []
|
in_progress_snapshots = []
|
||||||
|
|
||||||
@@ -96,14 +97,14 @@ def wipe_snapshots(client):
|
|||||||
assert in_progress_snapshots == []
|
assert in_progress_snapshots == []
|
||||||
|
|
||||||
|
|
||||||
def wipe_data_streams(client) -> None:
|
def wipe_data_streams(client: Any) -> None:
|
||||||
try:
|
try:
|
||||||
client.indices.delete_data_stream(name="*", expand_wildcards="all")
|
client.indices.delete_data_stream(name="*", expand_wildcards="all")
|
||||||
except Exception:
|
except Exception:
|
||||||
client.indices.delete_data_stream(name="*")
|
client.indices.delete_data_stream(name="*")
|
||||||
|
|
||||||
|
|
||||||
def wipe_indices(client) -> None:
|
def wipe_indices(client: Any) -> None:
|
||||||
client.indices.delete(
|
client.indices.delete(
|
||||||
index="*,-.ds-ilm-history-*",
|
index="*,-.ds-ilm-history-*",
|
||||||
expand_wildcards="all",
|
expand_wildcards="all",
|
||||||
@@ -111,7 +112,7 @@ def wipe_indices(client) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def wipe_searchable_snapshot_indices(client) -> None:
|
def wipe_searchable_snapshot_indices(client: Any) -> None:
|
||||||
cluster_metadata = client.cluster.state(
|
cluster_metadata = client.cluster.state(
|
||||||
metric="metadata",
|
metric="metadata",
|
||||||
filter_path="metadata.indices.*.settings.index.store.snapshot",
|
filter_path="metadata.indices.*.settings.index.store.snapshot",
|
||||||
@@ -121,17 +122,17 @@ def wipe_searchable_snapshot_indices(client) -> None:
|
|||||||
client.indices.delete(index=index)
|
client.indices.delete(index=index)
|
||||||
|
|
||||||
|
|
||||||
def wipe_slm_policies(client) -> None:
|
def wipe_slm_policies(client: Any) -> None:
|
||||||
for policy in client.slm.get_lifecycle():
|
for policy in client.slm.get_lifecycle():
|
||||||
client.slm.delete_lifecycle(policy_id=policy["name"])
|
client.slm.delete_lifecycle(policy_id=policy["name"])
|
||||||
|
|
||||||
|
|
||||||
def wipe_auto_follow_patterns(client) -> None:
|
def wipe_auto_follow_patterns(client: Any) -> None:
|
||||||
for pattern in client.ccr.get_auto_follow_pattern()["patterns"]:
|
for pattern in client.ccr.get_auto_follow_pattern()["patterns"]:
|
||||||
client.ccr.delete_auto_follow_pattern(name=pattern["name"])
|
client.ccr.delete_auto_follow_pattern(name=pattern["name"])
|
||||||
|
|
||||||
|
|
||||||
def wipe_node_shutdown_metadata(client) -> None:
|
def wipe_node_shutdown_metadata(client: Any) -> None:
|
||||||
shutdown_status = client.shutdown.get_node()
|
shutdown_status = client.shutdown.get_node()
|
||||||
# If response contains these two keys the feature flag isn't enabled
|
# If response contains these two keys the feature flag isn't enabled
|
||||||
# on this cluster so skip this step now.
|
# on this cluster so skip this step now.
|
||||||
@@ -143,14 +144,14 @@ def wipe_node_shutdown_metadata(client) -> None:
|
|||||||
client.shutdown.delete_node(node_id=node_id)
|
client.shutdown.delete_node(node_id=node_id)
|
||||||
|
|
||||||
|
|
||||||
def wipe_tasks(client) -> None:
|
def wipe_tasks(client: Any) -> None:
|
||||||
tasks = client.tasks.list()
|
tasks = client.tasks.list()
|
||||||
for node_name, node in tasks.get("node", {}).items():
|
for node_name, node in tasks.get("node", {}).items():
|
||||||
for task_id in node.get("tasks", ()):
|
for task_id in node.get("tasks", ()):
|
||||||
client.tasks.cancel(task_id=task_id, wait_for_completion=True)
|
client.tasks.cancel(task_id=task_id, wait_for_completion=True)
|
||||||
|
|
||||||
|
|
||||||
def wait_for_pending_tasks(client, filter, timeout: int = 30) -> None:
|
def wait_for_pending_tasks(client: Any, filter: Any, timeout: int = 30) -> None:
|
||||||
end_time = time.time() + timeout
|
end_time = time.time() + timeout
|
||||||
while time.time() < end_time:
|
while time.time() < end_time:
|
||||||
tasks = client.cat.tasks(detailed=True).split("\n")
|
tasks = client.cat.tasks(detailed=True).split("\n")
|
||||||
@@ -158,7 +159,7 @@ def wait_for_pending_tasks(client, filter, timeout: int = 30) -> None:
|
|||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
def wait_for_pending_datafeeds_and_jobs(client, timeout: int = 30) -> None:
|
def wait_for_pending_datafeeds_and_jobs(client: Any, timeout: int = 30) -> None:
|
||||||
end_time = time.time() + timeout
|
end_time = time.time() + timeout
|
||||||
while time.time() < end_time:
|
while time.time() < end_time:
|
||||||
if (
|
if (
|
||||||
@@ -171,7 +172,7 @@ def wait_for_pending_datafeeds_and_jobs(client, timeout: int = 30) -> None:
|
|||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
def wait_for_cluster_state_updates_to_finish(client, timeout: int = 30) -> None:
|
def wait_for_cluster_state_updates_to_finish(client: Any, timeout: int = 30) -> None:
|
||||||
end_time = time.time() + timeout
|
end_time = time.time() + timeout
|
||||||
while time.time() < end_time:
|
while time.time() < end_time:
|
||||||
if not client.cluster.pending_tasks().get("tasks", ()):
|
if not client.cluster.pending_tasks().get("tasks", ()):
|
||||||
|
|||||||
@@ -38,13 +38,14 @@ import shlex
|
|||||||
import shutil
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
tmp_dir = None
|
tmp_dir = None
|
||||||
|
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager # type: ignore
|
||||||
def set_tmp_dir():
|
def set_tmp_dir() -> None:
|
||||||
global tmp_dir
|
global tmp_dir
|
||||||
tmp_dir = tempfile.mkdtemp()
|
tmp_dir = tempfile.mkdtemp()
|
||||||
yield tmp_dir
|
yield tmp_dir
|
||||||
@@ -52,7 +53,7 @@ def set_tmp_dir():
|
|||||||
tmp_dir = None
|
tmp_dir = None
|
||||||
|
|
||||||
|
|
||||||
def run(*argv, expect_exit_code: int = 0) -> None:
|
def run(*argv: Any, expect_exit_code: int = 0) -> None:
|
||||||
global tmp_dir
|
global tmp_dir
|
||||||
if tmp_dir is None:
|
if tmp_dir is None:
|
||||||
os.chdir(base_dir)
|
os.chdir(base_dir)
|
||||||
@@ -70,9 +71,9 @@ def run(*argv, expect_exit_code: int = 0) -> None:
|
|||||||
exit(exit_code or 1)
|
exit(exit_code or 1)
|
||||||
|
|
||||||
|
|
||||||
def test_dist(dist) -> None:
|
def test_dist(dist: Any) -> None:
|
||||||
with set_tmp_dir() as tmp_dir:
|
with set_tmp_dir() as tmp_dir: # type: ignore
|
||||||
dist_name = re.match(
|
dist_name = re.match( # type: ignore
|
||||||
r"^(opensearchpy\d*)-",
|
r"^(opensearchpy\d*)-",
|
||||||
os.path.basename(dist)
|
os.path.basename(dist)
|
||||||
.replace("opensearch-py", "opensearchpy")
|
.replace("opensearch-py", "opensearchpy")
|
||||||
@@ -216,7 +217,7 @@ def main() -> None:
|
|||||||
# alpha/beta/rc -> aN/bN/rcN
|
# alpha/beta/rc -> aN/bN/rcN
|
||||||
else:
|
else:
|
||||||
pre_number = re.search(r"-(a|b|rc)(?:lpha|eta|)(\d+)$", expect_version)
|
pre_number = re.search(r"-(a|b|rc)(?:lpha|eta|)(\d+)$", expect_version)
|
||||||
version = version + pre_number.group(1) + pre_number.group(2)
|
version = version + pre_number.group(1) + pre_number.group(2) # type: ignore
|
||||||
|
|
||||||
expect_version = re.sub(
|
expect_version = re.sub(
|
||||||
r"(?:-(?:SNAPSHOT|alpha\d+|beta\d+|rc\d+))+$", "", expect_version
|
r"(?:-(?:SNAPSHOT|alpha\d+|beta\d+|rc\d+))+$", "", expect_version
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user