From 0716eda35c97a64fdf2770e92c00586b3038f2d7 Mon Sep 17 00:00:00 2001 From: dblock Date: Wed, 27 Nov 2024 11:42:32 -0500 Subject: [PATCH 1/2] Lifecycle integration tests. Signed-off-by: dblock --- DEVELOPER_GUIDE.md | 6 +- samples/hello/hello.py | 4 +- samples/hello/hello_async.py | 4 +- samples/hello/unicode.py | 63 ++++++++++++++++ samples/hello/unicode_async.py | 72 +++++++++++++++++++ .../test_async/test_server/test_clients.py | 47 ++++++++++++ test_opensearchpy/test_server/test_clients.py | 47 ++++++++++++ 7 files changed, 238 insertions(+), 5 deletions(-) create mode 100644 samples/hello/unicode.py create mode 100644 samples/hello/unicode_async.py diff --git a/DEVELOPER_GUIDE.md b/DEVELOPER_GUIDE.md index f544a520..218eb0b1 100644 --- a/DEVELOPER_GUIDE.md +++ b/DEVELOPER_GUIDE.md @@ -101,7 +101,11 @@ test_opensearchpy/test_connection.py::TestRequestsConnection::test_no_http_compr test_opensearchpy/test_async/test_connection.py::TestAIOHttpConnection::test_no_http_compression PASSED [100%] ``` -Note that integration tests require docker to be installed and running, and downloads quite a bit of data from over the internet and hence take few minutes to complete. +``` +./.ci/run-tests false 2.16.0 test_indices_lifecycle +``` + +Note that integration tests require docker to be installed and running, and downloads quite a bit of data from the internet and hence take few minutes to complete. ## Linter diff --git a/samples/hello/hello.py b/samples/hello/hello.py index 10dc3a35..d4d4ae69 100755 --- a/samples/hello/hello.py +++ b/samples/hello/hello.py @@ -19,9 +19,9 @@ def main() -> None: """ - an example showing how to create an synchronous connection to + An example showing how to create a synchronous connection to OpenSearch, create an index, index a document and search to - return the document + return the document. """ host = "localhost" port = 9200 diff --git a/samples/hello/hello_async.py b/samples/hello/hello_async.py index 983d7773..7f16a531 100755 --- a/samples/hello/hello_async.py +++ b/samples/hello/hello_async.py @@ -18,9 +18,9 @@ async def main() -> None: """ - an example showing how to create an asynchronous connection + An example showing how to create an asynchronous connection to OpenSearch, create an index, index a document and - search to return the document + search to return the document. """ # connect to OpenSearch host = "localhost" diff --git a/samples/hello/unicode.py b/samples/hello/unicode.py new file mode 100644 index 00000000..30a4b41e --- /dev/null +++ b/samples/hello/unicode.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python + +# SPDX-License-Identifier: Apache-2.0 +# +# The OpenSearch Contributors require contributions made to +# this file be licensed under the Apache-2.0 license or a +# compatible open source license. +# +# Modifications Copyright OpenSearch Contributors. See +# GitHub history for details. + + +import os + +from opensearchpy import OpenSearch + +# connect to OpenSearch + + +def main() -> None: + """ + An example showing how to create a synchronous connection to + OpenSearch, create an index, index a document and search to + return the document. + """ + host = "localhost" + port = 9200 + auth = ( + "admin", + os.getenv("OPENSEARCH_PASSWORD", "admin"), + ) # For testing only. Don't store credentials in code. + + client = OpenSearch( + hosts=[{"host": host, "port": port}], + http_auth=auth, + use_ssl=True, + verify_certs=False, + ssl_show_warn=False, + ) + + info = client.info() + print(f"Welcome to {info['version']['distribution']} {info['version']['number']}!") + + index_name = "кино" + index_create_result = client.indices.create(index=index_name) + print(index_create_result) + + document = {"название": "Солярис", "автор": "Андрей Тарковский", "год": "2011"} + id = "соларис@2011" + doc_insert_result = client.index( + index=index_name, body=document, id=id, refresh=True + ) + print(doc_insert_result) + + doc_delete_result = client.delete(index=index_name, id=id) + print(doc_delete_result) + + index_delete_result = client.indices.delete(index=index_name) + print(index_delete_result) + + +if __name__ == "__main__": + main() diff --git a/samples/hello/unicode_async.py b/samples/hello/unicode_async.py new file mode 100644 index 00000000..688832df --- /dev/null +++ b/samples/hello/unicode_async.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python + +# SPDX-License-Identifier: Apache-2.0 +# +# The OpenSearch Contributors require contributions made to +# this file be licensed under the Apache-2.0 license or a +# compatible open source license. +# +# Modifications Copyright OpenSearch Contributors. See +# GitHub history for details. + + +import asyncio +import os + +from opensearchpy import AsyncOpenSearch + + +async def main() -> None: + """ + An example showing how to create an asynchronous connection + to OpenSearch, create an index, index a document and + search to return the document. + """ + # connect to OpenSearch + host = "localhost" + port = 9200 + auth = ( + "admin", + os.getenv("OPENSEARCH_PASSWORD", "admin"), + ) # For testing only. Don't store credentials in code. + + client = AsyncOpenSearch( + hosts=[{"host": host, "port": port}], + http_auth=auth, + use_ssl=True, + verify_certs=False, + ssl_show_warn=False, + ) + + try: + info = await client.info() + print( + f"Welcome to {info['version']['distribution']} {info['version']['number']}!" + ) + + index_name = "кино" + index_create_result = await client.indices.create(index=index_name) + print(index_create_result) + + document = {"название": "Солярис", "автор": "Андрей Тарковский", "год": "2011"} + id = "соларис@2011" + doc_insert_result = await client.index( + index=index_name, body=document, id=id, refresh=True + ) + print(doc_insert_result) + + doc_delete_result = await client.delete(index=index_name, id=id) + print(doc_delete_result) + + index_delete_result = await client.indices.delete(index=index_name) + print(index_delete_result) + + finally: + await client.close() + + +if __name__ == "__main__": + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + loop.run_until_complete(main()) + loop.close() diff --git a/test_opensearchpy/test_async/test_server/test_clients.py b/test_opensearchpy/test_async/test_server/test_clients.py index f663f82f..282329c4 100644 --- a/test_opensearchpy/test_async/test_server/test_clients.py +++ b/test_opensearchpy/test_async/test_server/test_clients.py @@ -34,6 +34,53 @@ class TestUnicode: + async def test_indices_lifecycle_english(self, async_client: Any) -> None: + index_name = "movies" + + index_create_result = await async_client.indices.create(index=index_name) + assert index_create_result["acknowledged"] is True + assert index_name == index_create_result["index"] + + document = {"name": "Solaris", "director": "Andrei Tartakovsky", "year": "2011"} + id = "solaris@2011" + doc_insert_result = await async_client.index( + index=index_name, body=document, id=id, refresh=True + ) + assert "created" == doc_insert_result["result"] + assert index_name == doc_insert_result["_index"] + assert id == doc_insert_result["_id"] + + doc_delete_result = await async_client.delete(index=index_name, id=id) + assert "deleted" == doc_delete_result["result"] + assert index_name == doc_delete_result["_index"] + assert id == doc_delete_result["_id"] + + index_delete_result = await async_client.indices.delete(index=index_name) + assert index_delete_result["acknowledged"] is True + + async def test_indices_lifecycle_russian(self, async_client: Any) -> None: + index_name = "кино" + index_create_result = await async_client.indices.create(index=index_name) + assert index_create_result["acknowledged"] is True + assert index_name == index_create_result["index"] + + document = {"название": "Солярис", "автор": "Андрей Тарковский", "год": "2011"} + id = "соларис@2011" + doc_insert_result = await async_client.index( + index=index_name, body=document, id=id, refresh=True + ) + assert "created" == doc_insert_result["result"] + assert index_name == doc_insert_result["_index"] + assert id == doc_insert_result["_id"] + + doc_delete_result = await async_client.delete(index=index_name, id=id) + assert "deleted" == doc_delete_result["result"] + assert index_name == doc_delete_result["_index"] + assert id == doc_delete_result["_id"] + + index_delete_result = await async_client.indices.delete(index=index_name) + assert index_delete_result["acknowledged"] is True + async def test_indices_analyze(self, async_client: Any) -> None: await async_client.indices.analyze(body='{"text": "привет"}') diff --git a/test_opensearchpy/test_server/test_clients.py b/test_opensearchpy/test_server/test_clients.py index 7639a161..f43db08b 100644 --- a/test_opensearchpy/test_server/test_clients.py +++ b/test_opensearchpy/test_server/test_clients.py @@ -29,6 +29,53 @@ class TestUnicode(OpenSearchTestCase): + def test_indices_lifecycle_english(self) -> None: + index_name = "movies" + + index_create_result = self.client.indices.create(index=index_name) + self.assertTrue(index_create_result["acknowledged"]) + self.assertEqual(index_name, index_create_result["index"]) + + document = {"name": "Solaris", "director": "Andrei Tartakovsky", "year": "2011"} + id = "solaris@2011" + doc_insert_result = self.client.index( + index=index_name, body=document, id=id, refresh=True + ) + self.assertEqual("created", doc_insert_result["result"]) + self.assertEqual(index_name, doc_insert_result["_index"]) + self.assertEqual(id, doc_insert_result["_id"]) + + doc_delete_result = self.client.delete(index=index_name, id=id) + self.assertEqual("deleted", doc_delete_result["result"]) + self.assertEqual(index_name, doc_delete_result["_index"]) + self.assertEqual(id, doc_delete_result["_id"]) + + index_delete_result = self.client.indices.delete(index=index_name) + self.assertTrue(index_delete_result["acknowledged"]) + + def test_indices_lifecycle_russian(self) -> None: + index_name = "кино" + index_create_result = self.client.indices.create(index=index_name) + self.assertTrue(index_create_result["acknowledged"]) + self.assertEqual(index_name, index_create_result["index"]) + + document = {"название": "Солярис", "автор": "Андрей Тарковский", "год": "2011"} + id = "соларис@2011" + doc_insert_result = self.client.index( + index=index_name, body=document, id=id, refresh=True + ) + self.assertEqual("created", doc_insert_result["result"]) + self.assertEqual(index_name, doc_insert_result["_index"]) + self.assertEqual(id, doc_insert_result["_id"]) + + doc_delete_result = self.client.delete(index=index_name, id=id) + self.assertEqual("deleted", doc_delete_result["result"]) + self.assertEqual(index_name, doc_delete_result["_index"]) + self.assertEqual(id, doc_delete_result["_id"]) + + index_delete_result = self.client.indices.delete(index=index_name) + self.assertTrue(index_delete_result["acknowledged"]) + def test_indices_analyze(self) -> None: self.client.indices.analyze(body='{"text": "привет"}') From 2503919bad0f63393882a733cb986415b2ffb268 Mon Sep 17 00:00:00 2001 From: dblock Date: Wed, 27 Nov 2024 12:20:44 -0500 Subject: [PATCH 2/2] Added a test that makes sure the slash is properly encoded. Signed-off-by: dblock --- .../test_async/test_server/test_clients.py | 13 +++++++++++++ test_opensearchpy/test_server/test_clients.py | 15 +++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/test_opensearchpy/test_async/test_server/test_clients.py b/test_opensearchpy/test_async/test_server/test_clients.py index 282329c4..2ec7f0d0 100644 --- a/test_opensearchpy/test_async/test_server/test_clients.py +++ b/test_opensearchpy/test_async/test_server/test_clients.py @@ -30,9 +30,22 @@ import pytest from _pytest.mark.structures import MarkDecorator +from opensearchpy.exceptions import RequestError + pytestmark: MarkDecorator = pytest.mark.asyncio +class TestSpecialCharacters: + async def test_index_with_slash(self, async_client: Any) -> None: + index_name = "movies/shmovies" + with pytest.raises(RequestError) as e: + await async_client.indices.create(index=index_name) + assert ( + str(e.value) + == "RequestError(400, 'invalid_index_name_exception', 'Invalid index name [movies/shmovies], must not contain the following characters [ , \", *, \\\\, <, |, ,, >, /, ?]')" + ) + + class TestUnicode: async def test_indices_lifecycle_english(self, async_client: Any) -> None: index_name = "movies" diff --git a/test_opensearchpy/test_server/test_clients.py b/test_opensearchpy/test_server/test_clients.py index f43db08b..2363847b 100644 --- a/test_opensearchpy/test_server/test_clients.py +++ b/test_opensearchpy/test_server/test_clients.py @@ -25,9 +25,24 @@ # under the License. +import pytest + +from opensearchpy.exceptions import RequestError + from . import OpenSearchTestCase +class TestSpecialCharacters(OpenSearchTestCase): + def test_index_with_slash(self) -> None: + index_name = "movies/shmovies" + with pytest.raises(RequestError) as e: + self.client.indices.create(index=index_name) + self.assertEqual( + str(e.value), + "RequestError(400, 'invalid_index_name_exception', 'Invalid index name [movies/shmovies], must not contain the following characters [ , \", *, \\\\, <, |, ,, >, /, ?]')", + ) + + class TestUnicode(OpenSearchTestCase): def test_indices_lifecycle_english(self) -> None: index_name = "movies"