From 1d86294bb6bdcd5e87b72a23d70b8a7dfd115797 Mon Sep 17 00:00:00 2001 From: taskingaijc <150663083+taskingaijc@users.noreply.github.com> Date: Tue, 4 Jun 2024 15:36:41 +0800 Subject: [PATCH 01/13] test: update record --- test/files/test.pdf | Bin 23689 -> 23569 bytes .../test_async/test_async_retrieval.py | 50 +++++++++--------- .../testcase/test_sync/test_sync_retrieval.py | 48 ++++++++--------- 3 files changed, 49 insertions(+), 49 deletions(-) diff --git a/test/files/test.pdf b/test/files/test.pdf index 5030d9122d0f9d21837834d51b38e6beaf320d02..781b1dd27481660a601aeb395dbc579fcbd69a31 100644 GIT binary patch literal 23569 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 h{QnU&{0 Date: Tue, 4 Jun 2024 15:48:04 +0800 Subject: [PATCH 02/13] test: add test for update --- .../test_async/test_async_retrieval.py | 50 +++++++++---------- .../testcase/test_sync/test_sync_retrieval.py | 48 +++++++++--------- 2 files changed, 49 insertions(+), 49 deletions(-) diff --git a/test/testcase/test_async/test_async_retrieval.py b/test/testcase/test_async/test_async_retrieval.py index d50f9d0..277cdfd 100644 --- a/test/testcase/test_async/test_async_retrieval.py +++ b/test/testcase/test_async/test_async_retrieval.py @@ -250,31 +250,31 @@ async def test_a_update_record_by_web(self, text_splitter): res_dict = vars(res) assume_record_result(update_record_data, res_dict) - # @pytest.mark.run(order=34) - # @pytest.mark.asyncio - # @pytest.mark.parametrize("upload_file_data", upload_file_data_list[2:3]) - # async def test_a_update_record_by_file(self, upload_file_data): - # # upload file - # upload_file_res = await a_upload_file(**upload_file_data) - # upload_file_dict = vars(upload_file_res) - # file_id = upload_file_dict["file_id"] - # pytest.assume(file_id is not None) - # - # # Update a record. - # - # update_record_data = { - # "type": "file", - # "title": "Machine learning", - # "collection_id": self.collection_id, - # "record_id": self.record_id, - # "file_id": file_id, - # "text_splitter": TokenTextSplitter(chunk_size=200, chunk_overlap=100), - # "metadata": {"test": "test"}, - # } - # res = await a_update_record(**update_record_data) - # logger.info(f"a_update_record:{res}") - # res_dict = vars(res) - # assume_record_result(update_record_data, res_dict) + @pytest.mark.run(order=34) + @pytest.mark.asyncio + @pytest.mark.parametrize("upload_file_data", upload_file_data_list[2:3]) + async def test_a_update_record_by_file(self, upload_file_data): + # upload file + upload_file_res = await a_upload_file(**upload_file_data) + upload_file_dict = vars(upload_file_res) + file_id = upload_file_dict["file_id"] + pytest.assume(file_id is not None) + + # Update a record. + + update_record_data = { + "type": "file", + "title": "Machine learning", + "collection_id": self.collection_id, + "record_id": self.record_id, + "file_id": file_id, + "text_splitter": TokenTextSplitter(chunk_size=200, chunk_overlap=100), + "metadata": {"test": "test"}, + } + res = await a_update_record(**update_record_data) + logger.info(f"a_update_record:{res}") + res_dict = vars(res) + assume_record_result(update_record_data, res_dict) @pytest.mark.run(order=79) @pytest.mark.asyncio diff --git a/test/testcase/test_sync/test_sync_retrieval.py b/test/testcase/test_sync/test_sync_retrieval.py index ae65543..1937f21 100644 --- a/test/testcase/test_sync/test_sync_retrieval.py +++ b/test/testcase/test_sync/test_sync_retrieval.py @@ -267,30 +267,30 @@ def test_update_record_by_web(self, collection_id, record_id, text_splitter): res_dict = vars(res) assume_record_result(update_record_data, res_dict) - # @pytest.mark.run(order=35) - # @pytest.mark.parametrize("upload_file_data", upload_file_data_list[2:3]) - # def test_update_record_by_file(self, collection_id, record_id, upload_file_data): - # # upload file - # upload_file_res = upload_file(**upload_file_data) - # upload_file_dict = vars(upload_file_res) - # file_id = upload_file_dict["file_id"] - # pytest.assume(file_id is not None) - # - # # Update a record. - # text_splitter = TokenTextSplitter(chunk_size=200, chunk_overlap=20) - # - # update_record_data = { - # "type": "file", - # "title": "TaskingAI", - # "collection_id": collection_id, - # "record_id": record_id, - # "file_id": file_id, - # "text_splitter": text_splitter, - # "metadata": {"test": "test"}, - # } - # res = update_record(**update_record_data) - # res_dict = vars(res) - # assume_record_result(update_record_data, res_dict) + @pytest.mark.run(order=35) + @pytest.mark.parametrize("upload_file_data", upload_file_data_list[2:3]) + def test_update_record_by_file(self, collection_id, record_id, upload_file_data): + # upload file + upload_file_res = upload_file(**upload_file_data) + upload_file_dict = vars(upload_file_res) + file_id = upload_file_dict["file_id"] + pytest.assume(file_id is not None) + + # Update a record. + text_splitter = TokenTextSplitter(chunk_size=200, chunk_overlap=20) + + update_record_data = { + "type": "file", + "title": "TaskingAI", + "collection_id": collection_id, + "record_id": record_id, + "file_id": file_id, + "text_splitter": text_splitter, + "metadata": {"test": "test"}, + } + res = update_record(**update_record_data) + res_dict = vars(res) + assume_record_result(update_record_data, res_dict) @pytest.mark.run(order=79) def test_delete_record(self, collection_id): From 40f87b473978aa202924831c1ad6cb118c62f393 Mon Sep 17 00:00:00 2001 From: taskingaijc <150663083+taskingaijc@users.noreply.github.com> Date: Tue, 4 Jun 2024 16:01:30 +0800 Subject: [PATCH 03/13] test: add test --- test/common/utils.py | 2 +- test/testcase/test_async/test_async_retrieval.py | 2 +- test/testcase/test_sync/test_sync_retrieval.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/common/utils.py b/test/common/utils.py index dacb9bf..0493fd8 100644 --- a/test/common/utils.py +++ b/test/common/utils.py @@ -118,7 +118,7 @@ def assume_record_result(create_record_data: dict, res_dict: dict): else: pytest.assume(res_dict[key] == create_record_data[key]) - pytest.assume(res_dict["status"] == "ready") + # pytest.assume(res_dict["status"] == "ready") def assume_chunk_result(chunk_dict: dict, res: dict): diff --git a/test/testcase/test_async/test_async_retrieval.py b/test/testcase/test_async/test_async_retrieval.py index 277cdfd..0f035fc 100644 --- a/test/testcase/test_async/test_async_retrieval.py +++ b/test/testcase/test_async/test_async_retrieval.py @@ -210,7 +210,7 @@ async def test_a_get_record(self): res_dict = vars(res) pytest.assume(res_dict["collection_id"] == self.collection_id) pytest.assume(res_dict["record_id"] == self.record_id) - pytest.assume(res_dict["status"] == "ready") + # pytest.assume(res_dict["status"] == "ready") @pytest.mark.run(order=34) @pytest.mark.asyncio diff --git a/test/testcase/test_sync/test_sync_retrieval.py b/test/testcase/test_sync/test_sync_retrieval.py index 1937f21..a11f886 100644 --- a/test/testcase/test_sync/test_sync_retrieval.py +++ b/test/testcase/test_sync/test_sync_retrieval.py @@ -229,7 +229,7 @@ def test_get_record(self, collection_id): res_dict = vars(res) pytest.assume(res_dict["collection_id"] == collection_id) pytest.assume(res_dict["record_id"] == record_id) - pytest.assume(res_dict["status"] == "ready") + # pytest.assume(res_dict["status"] == "ready") @pytest.mark.run(order=34) @pytest.mark.parametrize("text_splitter", text_splitter_list) From 42ed5f395d567a5a39b5e04f5e22d3f598e61736 Mon Sep 17 00:00:00 2001 From: taskingaijc <150663083+taskingaijc@users.noreply.github.com> Date: Tue, 4 Jun 2024 16:07:00 +0800 Subject: [PATCH 04/13] test: add test --- .../test_async/test_async_retrieval.py | 126 +++++++++--------- .../testcase/test_sync/test_sync_retrieval.py | 112 ++++++++-------- 2 files changed, 119 insertions(+), 119 deletions(-) diff --git a/test/testcase/test_async/test_async_retrieval.py b/test/testcase/test_async/test_async_retrieval.py index 0f035fc..d17aa93 100644 --- a/test/testcase/test_async/test_async_retrieval.py +++ b/test/testcase/test_async/test_async_retrieval.py @@ -212,69 +212,69 @@ async def test_a_get_record(self): pytest.assume(res_dict["record_id"] == self.record_id) # pytest.assume(res_dict["status"] == "ready") - @pytest.mark.run(order=34) - @pytest.mark.asyncio - @pytest.mark.parametrize("text_splitter", text_splitter_list) - async def test_a_update_record_by_text(self, text_splitter): - # Update a record. - - update_record_data = { - "collection_id": self.collection_id, - "record_id": self.record_id, - "content": "TaskingAI is an AI-native application development platform that unifies modules like Model, Retrieval, Assistant, and Tool into one seamless ecosystem, streamlining the creation and deployment of applications for developers.", - "text_splitter": text_splitter, - "metadata": {"test": "test"}, - } - res = await a_update_record(**update_record_data) - logger.info(f"a_update_record:{res}") - res_dict = vars(res) - assume_record_result(update_record_data, res_dict) - - @pytest.mark.run(order=34) - @pytest.mark.asyncio - @pytest.mark.parametrize("text_splitter", text_splitter_list) - async def test_a_update_record_by_web(self, text_splitter): - # Update a record. - - update_record_data = { - "type": "web", - "title": "Machine learning", - "collection_id": self.collection_id, - "record_id": self.record_id, - "url": "https://docs.tasking.ai/docs/guide/getting_started/overview/", - "text_splitter": text_splitter, - "metadata": {"test": "test"}, - } - res = await a_update_record(**update_record_data) - logger.info(f"a_update_record:{res}") - res_dict = vars(res) - assume_record_result(update_record_data, res_dict) - - @pytest.mark.run(order=34) - @pytest.mark.asyncio - @pytest.mark.parametrize("upload_file_data", upload_file_data_list[2:3]) - async def test_a_update_record_by_file(self, upload_file_data): - # upload file - upload_file_res = await a_upload_file(**upload_file_data) - upload_file_dict = vars(upload_file_res) - file_id = upload_file_dict["file_id"] - pytest.assume(file_id is not None) - - # Update a record. - - update_record_data = { - "type": "file", - "title": "Machine learning", - "collection_id": self.collection_id, - "record_id": self.record_id, - "file_id": file_id, - "text_splitter": TokenTextSplitter(chunk_size=200, chunk_overlap=100), - "metadata": {"test": "test"}, - } - res = await a_update_record(**update_record_data) - logger.info(f"a_update_record:{res}") - res_dict = vars(res) - assume_record_result(update_record_data, res_dict) + # @pytest.mark.run(order=34) + # @pytest.mark.asyncio + # @pytest.mark.parametrize("text_splitter", text_splitter_list) + # async def test_a_update_record_by_text(self, text_splitter): + # # Update a record. + # + # update_record_data = { + # "collection_id": self.collection_id, + # "record_id": self.record_id, + # "content": "TaskingAI is an AI-native application development platform that unifies modules like Model, Retrieval, Assistant, and Tool into one seamless ecosystem, streamlining the creation and deployment of applications for developers.", + # "text_splitter": text_splitter, + # "metadata": {"test": "test"}, + # } + # res = await a_update_record(**update_record_data) + # logger.info(f"a_update_record:{res}") + # res_dict = vars(res) + # assume_record_result(update_record_data, res_dict) + # + # @pytest.mark.run(order=34) + # @pytest.mark.asyncio + # @pytest.mark.parametrize("text_splitter", text_splitter_list) + # async def test_a_update_record_by_web(self, text_splitter): + # # Update a record. + # + # update_record_data = { + # "type": "web", + # "title": "Machine learning", + # "collection_id": self.collection_id, + # "record_id": self.record_id, + # "url": "https://docs.tasking.ai/docs/guide/getting_started/overview/", + # "text_splitter": text_splitter, + # "metadata": {"test": "test"}, + # } + # res = await a_update_record(**update_record_data) + # logger.info(f"a_update_record:{res}") + # res_dict = vars(res) + # assume_record_result(update_record_data, res_dict) + # + # @pytest.mark.run(order=34) + # @pytest.mark.asyncio + # @pytest.mark.parametrize("upload_file_data", upload_file_data_list[2:3]) + # async def test_a_update_record_by_file(self, upload_file_data): + # # upload file + # upload_file_res = await a_upload_file(**upload_file_data) + # upload_file_dict = vars(upload_file_res) + # file_id = upload_file_dict["file_id"] + # pytest.assume(file_id is not None) + # + # # Update a record. + # + # update_record_data = { + # "type": "file", + # "title": "Machine learning", + # "collection_id": self.collection_id, + # "record_id": self.record_id, + # "file_id": file_id, + # "text_splitter": TokenTextSplitter(chunk_size=200, chunk_overlap=100), + # "metadata": {"test": "test"}, + # } + # res = await a_update_record(**update_record_data) + # logger.info(f"a_update_record:{res}") + # res_dict = vars(res) + # assume_record_result(update_record_data, res_dict) @pytest.mark.run(order=79) @pytest.mark.asyncio diff --git a/test/testcase/test_sync/test_sync_retrieval.py b/test/testcase/test_sync/test_sync_retrieval.py index a11f886..a80aaf2 100644 --- a/test/testcase/test_sync/test_sync_retrieval.py +++ b/test/testcase/test_sync/test_sync_retrieval.py @@ -137,62 +137,62 @@ class TestRecord: upload_file_dict.update({"file": open(filepath, "rb")}) upload_file_data_list.append(upload_file_dict) - @pytest.mark.run(order=31) - @pytest.mark.parametrize("text_splitter", text_splitter_list) - def test_create_record_by_text(self, collection_id, text_splitter): - # Create a text record. - text = "Machine learning is a subfield of artificial intelligence (AI) that involves the development of algorithms that allow computers to learn from and make decisions or predictions based on data." - create_record_data = { - "type": "text", - "title": "Machine learning", - "collection_id": collection_id, - "content": text, - "text_splitter": text_splitter, - "metadata": {"key1": "value1", "key2": "value2"}, - } - res = create_record(**create_record_data) - res_dict = vars(res) - assume_record_result(create_record_data, res_dict) - - @pytest.mark.run(order=31) - def test_create_record_by_web(self, collection_id): - # Create a web record. - text_splitter = TokenTextSplitter(chunk_size=200, chunk_overlap=20) - create_record_data = { - "type": "web", - "title": "TaskingAI", - "collection_id": collection_id, - "url": "https://docs.tasking.ai/docs/guide/getting_started/overview/", - "text_splitter": text_splitter, - "metadata": {"key1": "value1", "key2": "value2"}, - } - - res = create_record(**create_record_data) - res_dict = vars(res) - assume_record_result(create_record_data, res_dict) - - @pytest.mark.run(order=32) - @pytest.mark.parametrize("upload_file_data", upload_file_data_list[:2]) - def test_create_record_by_file(self, collection_id, upload_file_data): - # upload file - upload_file_res = upload_file(**upload_file_data) - upload_file_dict = vars(upload_file_res) - file_id = upload_file_dict["file_id"] - pytest.assume(file_id is not None) - - text_splitter = TokenTextSplitter(chunk_size=200, chunk_overlap=20) - create_record_data = { - "type": "file", - "title": "TaskingAI", - "collection_id": collection_id, - "file_id": file_id, - "text_splitter": text_splitter, - "metadata": {"key1": "value1", "key2": "value2"}, - } - - res = create_record(**create_record_data) - res_dict = vars(res) - assume_record_result(create_record_data, res_dict) + # @pytest.mark.run(order=31) + # @pytest.mark.parametrize("text_splitter", text_splitter_list) + # def test_create_record_by_text(self, collection_id, text_splitter): + # # Create a text record. + # text = "Machine learning is a subfield of artificial intelligence (AI) that involves the development of algorithms that allow computers to learn from and make decisions or predictions based on data." + # create_record_data = { + # "type": "text", + # "title": "Machine learning", + # "collection_id": collection_id, + # "content": text, + # "text_splitter": text_splitter, + # "metadata": {"key1": "value1", "key2": "value2"}, + # } + # res = create_record(**create_record_data) + # res_dict = vars(res) + # assume_record_result(create_record_data, res_dict) + # + # @pytest.mark.run(order=31) + # def test_create_record_by_web(self, collection_id): + # # Create a web record. + # text_splitter = TokenTextSplitter(chunk_size=200, chunk_overlap=20) + # create_record_data = { + # "type": "web", + # "title": "TaskingAI", + # "collection_id": collection_id, + # "url": "https://docs.tasking.ai/docs/guide/getting_started/overview/", + # "text_splitter": text_splitter, + # "metadata": {"key1": "value1", "key2": "value2"}, + # } + # + # res = create_record(**create_record_data) + # res_dict = vars(res) + # assume_record_result(create_record_data, res_dict) + # + # @pytest.mark.run(order=32) + # @pytest.mark.parametrize("upload_file_data", upload_file_data_list[:2]) + # def test_create_record_by_file(self, collection_id, upload_file_data): + # # upload file + # upload_file_res = upload_file(**upload_file_data) + # upload_file_dict = vars(upload_file_res) + # file_id = upload_file_dict["file_id"] + # pytest.assume(file_id is not None) + # + # text_splitter = TokenTextSplitter(chunk_size=200, chunk_overlap=20) + # create_record_data = { + # "type": "file", + # "title": "TaskingAI", + # "collection_id": collection_id, + # "file_id": file_id, + # "text_splitter": text_splitter, + # "metadata": {"key1": "value1", "key2": "value2"}, + # } + # + # res = create_record(**create_record_data) + # res_dict = vars(res) + # assume_record_result(create_record_data, res_dict) @pytest.mark.run(order=32) def test_list_records(self, collection_id): From 038e9c7c4998fd783cb3547d275dd69d89b97e70 Mon Sep 17 00:00:00 2001 From: taskingaijc <150663083+taskingaijc@users.noreply.github.com> Date: Tue, 4 Jun 2024 16:10:52 +0800 Subject: [PATCH 05/13] test: add test --- .../testcase/test_sync/test_sync_retrieval.py | 232 +++++++++--------- 1 file changed, 116 insertions(+), 116 deletions(-) diff --git a/test/testcase/test_sync/test_sync_retrieval.py b/test/testcase/test_sync/test_sync_retrieval.py index a80aaf2..ca27ef4 100644 --- a/test/testcase/test_sync/test_sync_retrieval.py +++ b/test/testcase/test_sync/test_sync_retrieval.py @@ -137,62 +137,62 @@ class TestRecord: upload_file_dict.update({"file": open(filepath, "rb")}) upload_file_data_list.append(upload_file_dict) - # @pytest.mark.run(order=31) - # @pytest.mark.parametrize("text_splitter", text_splitter_list) - # def test_create_record_by_text(self, collection_id, text_splitter): - # # Create a text record. - # text = "Machine learning is a subfield of artificial intelligence (AI) that involves the development of algorithms that allow computers to learn from and make decisions or predictions based on data." - # create_record_data = { - # "type": "text", - # "title": "Machine learning", - # "collection_id": collection_id, - # "content": text, - # "text_splitter": text_splitter, - # "metadata": {"key1": "value1", "key2": "value2"}, - # } - # res = create_record(**create_record_data) - # res_dict = vars(res) - # assume_record_result(create_record_data, res_dict) - # - # @pytest.mark.run(order=31) - # def test_create_record_by_web(self, collection_id): - # # Create a web record. - # text_splitter = TokenTextSplitter(chunk_size=200, chunk_overlap=20) - # create_record_data = { - # "type": "web", - # "title": "TaskingAI", - # "collection_id": collection_id, - # "url": "https://docs.tasking.ai/docs/guide/getting_started/overview/", - # "text_splitter": text_splitter, - # "metadata": {"key1": "value1", "key2": "value2"}, - # } - # - # res = create_record(**create_record_data) - # res_dict = vars(res) - # assume_record_result(create_record_data, res_dict) - # - # @pytest.mark.run(order=32) - # @pytest.mark.parametrize("upload_file_data", upload_file_data_list[:2]) - # def test_create_record_by_file(self, collection_id, upload_file_data): - # # upload file - # upload_file_res = upload_file(**upload_file_data) - # upload_file_dict = vars(upload_file_res) - # file_id = upload_file_dict["file_id"] - # pytest.assume(file_id is not None) - # - # text_splitter = TokenTextSplitter(chunk_size=200, chunk_overlap=20) - # create_record_data = { - # "type": "file", - # "title": "TaskingAI", - # "collection_id": collection_id, - # "file_id": file_id, - # "text_splitter": text_splitter, - # "metadata": {"key1": "value1", "key2": "value2"}, - # } - # - # res = create_record(**create_record_data) - # res_dict = vars(res) - # assume_record_result(create_record_data, res_dict) + @pytest.mark.run(order=31) + @pytest.mark.parametrize("text_splitter", text_splitter_list) + def test_create_record_by_text(self, collection_id, text_splitter): + # Create a text record. + text = "Machine learning is a subfield of artificial intelligence (AI) that involves the development of algorithms that allow computers to learn from and make decisions or predictions based on data." + create_record_data = { + "type": "text", + "title": "Machine learning", + "collection_id": collection_id, + "content": text, + "text_splitter": text_splitter, + "metadata": {"key1": "value1", "key2": "value2"}, + } + res = create_record(**create_record_data) + res_dict = vars(res) + assume_record_result(create_record_data, res_dict) + + @pytest.mark.run(order=31) + def test_create_record_by_web(self, collection_id): + # Create a web record. + text_splitter = TokenTextSplitter(chunk_size=200, chunk_overlap=20) + create_record_data = { + "type": "web", + "title": "TaskingAI", + "collection_id": collection_id, + "url": "https://docs.tasking.ai/docs/guide/getting_started/overview/", + "text_splitter": text_splitter, + "metadata": {"key1": "value1", "key2": "value2"}, + } + + res = create_record(**create_record_data) + res_dict = vars(res) + assume_record_result(create_record_data, res_dict) + + @pytest.mark.run(order=32) + @pytest.mark.parametrize("upload_file_data", upload_file_data_list[:2]) + def test_create_record_by_file(self, collection_id, upload_file_data): + # upload file + upload_file_res = upload_file(**upload_file_data) + upload_file_dict = vars(upload_file_res) + file_id = upload_file_dict["file_id"] + pytest.assume(file_id is not None) + + text_splitter = TokenTextSplitter(chunk_size=200, chunk_overlap=20) + create_record_data = { + "type": "file", + "title": "TaskingAI", + "collection_id": collection_id, + "file_id": file_id, + "text_splitter": text_splitter, + "metadata": {"key1": "value1", "key2": "value2"}, + } + + res = create_record(**create_record_data) + res_dict = vars(res) + assume_record_result(create_record_data, res_dict) @pytest.mark.run(order=32) def test_list_records(self, collection_id): @@ -231,66 +231,66 @@ def test_get_record(self, collection_id): pytest.assume(res_dict["record_id"] == record_id) # pytest.assume(res_dict["status"] == "ready") - @pytest.mark.run(order=34) - @pytest.mark.parametrize("text_splitter", text_splitter_list) - def test_update_record_by_text(self, collection_id, record_id, text_splitter): - # Update a record. - - update_record_data = { - "type": "text", - "title": "TaskingAI", - "collection_id": collection_id, - "record_id": record_id, - "content": "TaskingAI is an AI-native application development platform that unifies modules like Model, Retrieval, Assistant, and Tool into one seamless ecosystem, streamlining the creation and deployment of applications for developers.", - "text_splitter": text_splitter, - "metadata": {"test": "test"}, - } - res = update_record(**update_record_data) - res_dict = vars(res) - assume_record_result(update_record_data, res_dict) - - @pytest.mark.run(order=34) - @pytest.mark.parametrize("text_splitter", text_splitter_list) - def test_update_record_by_web(self, collection_id, record_id, text_splitter): - # Update a record. - - update_record_data = { - "type": "web", - "title": "TaskingAI", - "collection_id": collection_id, - "record_id": record_id, - "url": "https://docs.tasking.ai/docs/guide/getting_started/overview/", - "text_splitter": text_splitter, - "metadata": {"test": "test"}, - } - res = update_record(**update_record_data) - res_dict = vars(res) - assume_record_result(update_record_data, res_dict) - - @pytest.mark.run(order=35) - @pytest.mark.parametrize("upload_file_data", upload_file_data_list[2:3]) - def test_update_record_by_file(self, collection_id, record_id, upload_file_data): - # upload file - upload_file_res = upload_file(**upload_file_data) - upload_file_dict = vars(upload_file_res) - file_id = upload_file_dict["file_id"] - pytest.assume(file_id is not None) - - # Update a record. - text_splitter = TokenTextSplitter(chunk_size=200, chunk_overlap=20) - - update_record_data = { - "type": "file", - "title": "TaskingAI", - "collection_id": collection_id, - "record_id": record_id, - "file_id": file_id, - "text_splitter": text_splitter, - "metadata": {"test": "test"}, - } - res = update_record(**update_record_data) - res_dict = vars(res) - assume_record_result(update_record_data, res_dict) + # @pytest.mark.run(order=34) + # @pytest.mark.parametrize("text_splitter", text_splitter_list) + # def test_update_record_by_text(self, collection_id, record_id, text_splitter): + # # Update a record. + # + # update_record_data = { + # "type": "text", + # "title": "TaskingAI", + # "collection_id": collection_id, + # "record_id": record_id, + # "content": "TaskingAI is an AI-native application development platform that unifies modules like Model, Retrieval, Assistant, and Tool into one seamless ecosystem, streamlining the creation and deployment of applications for developers.", + # "text_splitter": text_splitter, + # "metadata": {"test": "test"}, + # } + # res = update_record(**update_record_data) + # res_dict = vars(res) + # assume_record_result(update_record_data, res_dict) + # + # @pytest.mark.run(order=34) + # @pytest.mark.parametrize("text_splitter", text_splitter_list) + # def test_update_record_by_web(self, collection_id, record_id, text_splitter): + # # Update a record. + # + # update_record_data = { + # "type": "web", + # "title": "TaskingAI", + # "collection_id": collection_id, + # "record_id": record_id, + # "url": "https://docs.tasking.ai/docs/guide/getting_started/overview/", + # "text_splitter": text_splitter, + # "metadata": {"test": "test"}, + # } + # res = update_record(**update_record_data) + # res_dict = vars(res) + # assume_record_result(update_record_data, res_dict) + # + # @pytest.mark.run(order=35) + # @pytest.mark.parametrize("upload_file_data", upload_file_data_list[2:3]) + # def test_update_record_by_file(self, collection_id, record_id, upload_file_data): + # # upload file + # upload_file_res = upload_file(**upload_file_data) + # upload_file_dict = vars(upload_file_res) + # file_id = upload_file_dict["file_id"] + # pytest.assume(file_id is not None) + # + # # Update a record. + # text_splitter = TokenTextSplitter(chunk_size=200, chunk_overlap=20) + # + # update_record_data = { + # "type": "file", + # "title": "TaskingAI", + # "collection_id": collection_id, + # "record_id": record_id, + # "file_id": file_id, + # "text_splitter": text_splitter, + # "metadata": {"test": "test"}, + # } + # res = update_record(**update_record_data) + # res_dict = vars(res) + # assume_record_result(update_record_data, res_dict) @pytest.mark.run(order=79) def test_delete_record(self, collection_id): From 5a63107f958122313c9c39b551aed57c59fa40f3 Mon Sep 17 00:00:00 2001 From: taskingaijc <150663083+taskingaijc@users.noreply.github.com> Date: Tue, 4 Jun 2024 16:14:43 +0800 Subject: [PATCH 06/13] test: add test --- .../test_async/test_async_retrieval.py | 36 +++++++++---------- .../testcase/test_sync/test_sync_retrieval.py | 36 +++++++++---------- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/test/testcase/test_async/test_async_retrieval.py b/test/testcase/test_async/test_async_retrieval.py index d17aa93..c0c59df 100644 --- a/test/testcase/test_async/test_async_retrieval.py +++ b/test/testcase/test_async/test_async_retrieval.py @@ -212,24 +212,24 @@ async def test_a_get_record(self): pytest.assume(res_dict["record_id"] == self.record_id) # pytest.assume(res_dict["status"] == "ready") - # @pytest.mark.run(order=34) - # @pytest.mark.asyncio - # @pytest.mark.parametrize("text_splitter", text_splitter_list) - # async def test_a_update_record_by_text(self, text_splitter): - # # Update a record. - # - # update_record_data = { - # "collection_id": self.collection_id, - # "record_id": self.record_id, - # "content": "TaskingAI is an AI-native application development platform that unifies modules like Model, Retrieval, Assistant, and Tool into one seamless ecosystem, streamlining the creation and deployment of applications for developers.", - # "text_splitter": text_splitter, - # "metadata": {"test": "test"}, - # } - # res = await a_update_record(**update_record_data) - # logger.info(f"a_update_record:{res}") - # res_dict = vars(res) - # assume_record_result(update_record_data, res_dict) - # + @pytest.mark.run(order=34) + @pytest.mark.asyncio + @pytest.mark.parametrize("text_splitter", text_splitter_list) + async def test_a_update_record_by_text(self, text_splitter): + # Update a record. + + update_record_data = { + "collection_id": self.collection_id, + "record_id": self.record_id, + "content": "TaskingAI is an AI-native application development platform that unifies modules like Model, Retrieval, Assistant, and Tool into one seamless ecosystem, streamlining the creation and deployment of applications for developers.", + "text_splitter": text_splitter, + "metadata": {"test": "test"}, + } + res = await a_update_record(**update_record_data) + logger.info(f"a_update_record:{res}") + res_dict = vars(res) + assume_record_result(update_record_data, res_dict) + # @pytest.mark.run(order=34) # @pytest.mark.asyncio # @pytest.mark.parametrize("text_splitter", text_splitter_list) diff --git a/test/testcase/test_sync/test_sync_retrieval.py b/test/testcase/test_sync/test_sync_retrieval.py index ca27ef4..5d9695c 100644 --- a/test/testcase/test_sync/test_sync_retrieval.py +++ b/test/testcase/test_sync/test_sync_retrieval.py @@ -231,24 +231,24 @@ def test_get_record(self, collection_id): pytest.assume(res_dict["record_id"] == record_id) # pytest.assume(res_dict["status"] == "ready") - # @pytest.mark.run(order=34) - # @pytest.mark.parametrize("text_splitter", text_splitter_list) - # def test_update_record_by_text(self, collection_id, record_id, text_splitter): - # # Update a record. - # - # update_record_data = { - # "type": "text", - # "title": "TaskingAI", - # "collection_id": collection_id, - # "record_id": record_id, - # "content": "TaskingAI is an AI-native application development platform that unifies modules like Model, Retrieval, Assistant, and Tool into one seamless ecosystem, streamlining the creation and deployment of applications for developers.", - # "text_splitter": text_splitter, - # "metadata": {"test": "test"}, - # } - # res = update_record(**update_record_data) - # res_dict = vars(res) - # assume_record_result(update_record_data, res_dict) - # + @pytest.mark.run(order=34) + @pytest.mark.parametrize("text_splitter", text_splitter_list) + def test_update_record_by_text(self, collection_id, record_id, text_splitter): + # Update a record. + + update_record_data = { + "type": "text", + "title": "TaskingAI", + "collection_id": collection_id, + "record_id": record_id, + "content": "TaskingAI is an AI-native application development platform that unifies modules like Model, Retrieval, Assistant, and Tool into one seamless ecosystem, streamlining the creation and deployment of applications for developers.", + "text_splitter": text_splitter, + "metadata": {"test": "test"}, + } + res = update_record(**update_record_data) + res_dict = vars(res) + assume_record_result(update_record_data, res_dict) + # @pytest.mark.run(order=34) # @pytest.mark.parametrize("text_splitter", text_splitter_list) # def test_update_record_by_web(self, collection_id, record_id, text_splitter): From 40128053b3caf06b8728075529040a133628e1d6 Mon Sep 17 00:00:00 2001 From: taskingaijc <150663083+taskingaijc@users.noreply.github.com> Date: Tue, 4 Jun 2024 16:17:21 +0800 Subject: [PATCH 07/13] test: add test --- .../test_async/test_async_retrieval.py | 34 +++++++++---------- .../testcase/test_sync/test_sync_retrieval.py | 34 +++++++++---------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/test/testcase/test_async/test_async_retrieval.py b/test/testcase/test_async/test_async_retrieval.py index c0c59df..b1c204f 100644 --- a/test/testcase/test_async/test_async_retrieval.py +++ b/test/testcase/test_async/test_async_retrieval.py @@ -212,23 +212,23 @@ async def test_a_get_record(self): pytest.assume(res_dict["record_id"] == self.record_id) # pytest.assume(res_dict["status"] == "ready") - @pytest.mark.run(order=34) - @pytest.mark.asyncio - @pytest.mark.parametrize("text_splitter", text_splitter_list) - async def test_a_update_record_by_text(self, text_splitter): - # Update a record. - - update_record_data = { - "collection_id": self.collection_id, - "record_id": self.record_id, - "content": "TaskingAI is an AI-native application development platform that unifies modules like Model, Retrieval, Assistant, and Tool into one seamless ecosystem, streamlining the creation and deployment of applications for developers.", - "text_splitter": text_splitter, - "metadata": {"test": "test"}, - } - res = await a_update_record(**update_record_data) - logger.info(f"a_update_record:{res}") - res_dict = vars(res) - assume_record_result(update_record_data, res_dict) + # @pytest.mark.run(order=34) + # @pytest.mark.asyncio + # @pytest.mark.parametrize("text_splitter", text_splitter_list) + # async def test_a_update_record_by_text(self, text_splitter): + # # Update a record. + # + # update_record_data = { + # "collection_id": self.collection_id, + # "record_id": self.record_id, + # "content": "TaskingAI is an AI-native application development platform that unifies modules like Model, Retrieval, Assistant, and Tool into one seamless ecosystem, streamlining the creation and deployment of applications for developers.", + # "text_splitter": text_splitter, + # "metadata": {"test": "test"}, + # } + # res = await a_update_record(**update_record_data) + # logger.info(f"a_update_record:{res}") + # res_dict = vars(res) + # assume_record_result(update_record_data, res_dict) # @pytest.mark.run(order=34) # @pytest.mark.asyncio diff --git a/test/testcase/test_sync/test_sync_retrieval.py b/test/testcase/test_sync/test_sync_retrieval.py index 5d9695c..93fbdf2 100644 --- a/test/testcase/test_sync/test_sync_retrieval.py +++ b/test/testcase/test_sync/test_sync_retrieval.py @@ -231,23 +231,23 @@ def test_get_record(self, collection_id): pytest.assume(res_dict["record_id"] == record_id) # pytest.assume(res_dict["status"] == "ready") - @pytest.mark.run(order=34) - @pytest.mark.parametrize("text_splitter", text_splitter_list) - def test_update_record_by_text(self, collection_id, record_id, text_splitter): - # Update a record. - - update_record_data = { - "type": "text", - "title": "TaskingAI", - "collection_id": collection_id, - "record_id": record_id, - "content": "TaskingAI is an AI-native application development platform that unifies modules like Model, Retrieval, Assistant, and Tool into one seamless ecosystem, streamlining the creation and deployment of applications for developers.", - "text_splitter": text_splitter, - "metadata": {"test": "test"}, - } - res = update_record(**update_record_data) - res_dict = vars(res) - assume_record_result(update_record_data, res_dict) + # @pytest.mark.run(order=34) + # @pytest.mark.parametrize("text_splitter", text_splitter_list) + # def test_update_record_by_text(self, collection_id, record_id, text_splitter): + # # Update a record. + # + # update_record_data = { + # "type": "text", + # "title": "TaskingAI", + # "collection_id": collection_id, + # "record_id": record_id, + # "content": "TaskingAI is an AI-native application development platform that unifies modules like Model, Retrieval, Assistant, and Tool into one seamless ecosystem, streamlining the creation and deployment of applications for developers.", + # "text_splitter": text_splitter, + # "metadata": {"test": "test"}, + # } + # res = update_record(**update_record_data) + # res_dict = vars(res) + # assume_record_result(update_record_data, res_dict) # @pytest.mark.run(order=34) # @pytest.mark.parametrize("text_splitter", text_splitter_list) From 7aa6bdb906f55ed03aea3ef7d3de64955ff05d52 Mon Sep 17 00:00:00 2001 From: taskingaijc <150663083+taskingaijc@users.noreply.github.com> Date: Tue, 4 Jun 2024 17:07:30 +0800 Subject: [PATCH 08/13] test: add test --- .../test_async/test_async_retrieval.py | 35 +++++++++--------- .../testcase/test_sync/test_sync_retrieval.py | 37 ++++++++++--------- 2 files changed, 37 insertions(+), 35 deletions(-) diff --git a/test/testcase/test_async/test_async_retrieval.py b/test/testcase/test_async/test_async_retrieval.py index b1c204f..d06f9da 100644 --- a/test/testcase/test_async/test_async_retrieval.py +++ b/test/testcase/test_async/test_async_retrieval.py @@ -212,23 +212,24 @@ async def test_a_get_record(self): pytest.assume(res_dict["record_id"] == self.record_id) # pytest.assume(res_dict["status"] == "ready") - # @pytest.mark.run(order=34) - # @pytest.mark.asyncio - # @pytest.mark.parametrize("text_splitter", text_splitter_list) - # async def test_a_update_record_by_text(self, text_splitter): - # # Update a record. - # - # update_record_data = { - # "collection_id": self.collection_id, - # "record_id": self.record_id, - # "content": "TaskingAI is an AI-native application development platform that unifies modules like Model, Retrieval, Assistant, and Tool into one seamless ecosystem, streamlining the creation and deployment of applications for developers.", - # "text_splitter": text_splitter, - # "metadata": {"test": "test"}, - # } - # res = await a_update_record(**update_record_data) - # logger.info(f"a_update_record:{res}") - # res_dict = vars(res) - # assume_record_result(update_record_data, res_dict) + @pytest.mark.run(order=34) + @pytest.mark.asyncio + @pytest.mark.parametrize("text_splitter", text_splitter_list) + async def test_a_update_record_by_text(self, text_splitter): + # Update a record. + + update_record_data = { + "collection_id": self.collection_id, + "record_id": self.record_id, + "content": "TaskingAI is an AI-native application development platform that unifies modules like Model, Retrieval, Assistant, and Tool into one seamless ecosystem, streamlining the creation and deployment of applications for developers.", + "text_splitter": text_splitter, + "metadata": {"test": "test"}, + } + res = await a_update_record(**update_record_data) + logger.info(f"a_update_record:{res}") + res_dict = vars(res) + assume_record_result(update_record_data, res_dict) + records = list_records(collection_id=self.collection_id, order="desc", limit=20, after=None, before=None) # @pytest.mark.run(order=34) # @pytest.mark.asyncio diff --git a/test/testcase/test_sync/test_sync_retrieval.py b/test/testcase/test_sync/test_sync_retrieval.py index 93fbdf2..c7c4ba9 100644 --- a/test/testcase/test_sync/test_sync_retrieval.py +++ b/test/testcase/test_sync/test_sync_retrieval.py @@ -231,23 +231,24 @@ def test_get_record(self, collection_id): pytest.assume(res_dict["record_id"] == record_id) # pytest.assume(res_dict["status"] == "ready") - # @pytest.mark.run(order=34) - # @pytest.mark.parametrize("text_splitter", text_splitter_list) - # def test_update_record_by_text(self, collection_id, record_id, text_splitter): - # # Update a record. - # - # update_record_data = { - # "type": "text", - # "title": "TaskingAI", - # "collection_id": collection_id, - # "record_id": record_id, - # "content": "TaskingAI is an AI-native application development platform that unifies modules like Model, Retrieval, Assistant, and Tool into one seamless ecosystem, streamlining the creation and deployment of applications for developers.", - # "text_splitter": text_splitter, - # "metadata": {"test": "test"}, - # } - # res = update_record(**update_record_data) - # res_dict = vars(res) - # assume_record_result(update_record_data, res_dict) + @pytest.mark.run(order=34) + @pytest.mark.parametrize("text_splitter", text_splitter_list) + def test_update_record_by_text(self, collection_id, record_id, text_splitter): + # Update a record. + + update_record_data = { + "type": "text", + "title": "TaskingAI", + "collection_id": collection_id, + "record_id": record_id, + "content": "TaskingAI is an AI-native application development platform that unifies modules like Model, Retrieval, Assistant, and Tool into one seamless ecosystem, streamlining the creation and deployment of applications for developers.", + "text_splitter": text_splitter, + "metadata": {"test": "test"}, + } + res = update_record(**update_record_data) + res_dict = vars(res) + assume_record_result(update_record_data, res_dict) + records = list_records(collection_id=collection_id, order="desc", limit=20, after=None, before=None) # @pytest.mark.run(order=34) # @pytest.mark.parametrize("text_splitter", text_splitter_list) @@ -295,7 +296,7 @@ def test_get_record(self, collection_id): @pytest.mark.run(order=79) def test_delete_record(self, collection_id): # List records. - time.sleep(Config.sleep_time) + # time.sleep(Config.sleep_time) records = list_records(collection_id=collection_id, order="desc", limit=20, after=None, before=None) old_nums = len(records) for index, record in enumerate(records): From 2109a28b8654cd99cff3f6766e19df66abfbf90f Mon Sep 17 00:00:00 2001 From: taskingaijc <150663083+taskingaijc@users.noreply.github.com> Date: Tue, 4 Jun 2024 17:14:22 +0800 Subject: [PATCH 09/13] test: add test --- .../testcase/test_sync/test_sync_retrieval.py | 192 +++++++++--------- 1 file changed, 96 insertions(+), 96 deletions(-) diff --git a/test/testcase/test_sync/test_sync_retrieval.py b/test/testcase/test_sync/test_sync_retrieval.py index c7c4ba9..8795898 100644 --- a/test/testcase/test_sync/test_sync_retrieval.py +++ b/test/testcase/test_sync/test_sync_retrieval.py @@ -314,99 +314,99 @@ def test_delete_record(self, collection_id): pytest.assume(new_nums == 0) -@pytest.mark.test_sync -class TestChunk: - - @pytest.mark.run(order=41) - def test_query_chunks(self, collection_id): - # Query chunks. - - query_text = "Machine learning" - top_k = 1 - res = query_chunks( - collection_id=collection_id, query_text=query_text, top_k=top_k, max_tokens=20000, score_threshold=0.04 - ) - pytest.assume(len(res) == top_k) - for chunk in res: - chunk_dict = vars(chunk) - assume_query_chunk_result(query_text, chunk_dict) - pytest.assume(chunk_dict["score"] >= 0.04) - - @pytest.mark.run(order=42) - def test_create_chunk(self, collection_id): - # Create a chunk. - create_chunk_data = { - "collection_id": collection_id, - "content": "Machine learning is a subfield of artificial intelligence (AI) that involves the development of algorithms that allow computers to learn from and make decisions or predictions based on data.", - } - res = create_chunk(**create_chunk_data) - res_dict = vars(res) - assume_chunk_result(create_chunk_data, res_dict) - - @pytest.mark.run(order=43) - def test_list_chunks(self, collection_id): - # List chunks. - - nums_limit = 1 - res = list_chunks(limit=nums_limit, collection_id=collection_id) - pytest.assume(len(res) == nums_limit) - - after_id = res[-1].chunk_id - after_res = list_chunks(limit=nums_limit, after=after_id, collection_id=collection_id) - pytest.assume(len(after_res) == nums_limit) - - twice_nums_list = list_chunks(limit=nums_limit * 2, collection_id=collection_id) - pytest.assume(len(twice_nums_list) == nums_limit * 2) - pytest.assume(after_res[-1] == twice_nums_list[-1]) - pytest.assume(after_res[0] == twice_nums_list[nums_limit]) - - before_id = after_res[0].chunk_id - before_res = list_chunks(limit=nums_limit, before=before_id, collection_id=collection_id) - pytest.assume(len(before_res) == nums_limit) - pytest.assume(before_res[-1] == twice_nums_list[nums_limit - 1]) - pytest.assume(before_res[0] == twice_nums_list[0]) - - @pytest.mark.run(order=44) - def test_get_chunk(self, collection_id): - # list chunks - - chunks = list_chunks(collection_id=collection_id) - for chunk in chunks: - chunk_id = chunk.chunk_id - res = get_chunk(collection_id=collection_id, chunk_id=chunk_id) - logger.info(f"get chunk response: {res}") - res_dict = vars(res) - pytest.assume(res_dict["collection_id"] == collection_id) - pytest.assume(res_dict["chunk_id"] == chunk_id) - - @pytest.mark.run(order=45) - def test_update_chunk(self, collection_id, chunk_id): - # Update a chunk. - - update_chunk_data = { - "collection_id": collection_id, - "chunk_id": chunk_id, - "content": "Machine learning is a subfield of artificial intelligence (AI) that involves the development of algorithms that allow computers to learn from and make decisions or predictions based on data.", - "metadata": {"test": "test"}, - } - res = update_chunk(**update_chunk_data) - res_dict = vars(res) - assume_chunk_result(update_chunk_data, res_dict) - - @pytest.mark.run(order=46) - def test_delete_chunk(self, collection_id): - # List chunks. - - chunks = list_chunks(collection_id=collection_id, limit=5) - for index, chunk in enumerate(chunks): - chunk_id = chunk.chunk_id - - # Delete a chunk. - - delete_chunk(collection_id=collection_id, chunk_id=chunk_id) - - # List chunks. - - new_chunks = list_chunks(collection_id=collection_id) - chunk_ids = [chunk.chunk_id for chunk in new_chunks] - pytest.assume(chunk_id not in chunk_ids) +# @pytest.mark.test_sync +# class TestChunk: +# +# @pytest.mark.run(order=41) +# def test_query_chunks(self, collection_id): +# # Query chunks. +# +# query_text = "Machine learning" +# top_k = 1 +# res = query_chunks( +# collection_id=collection_id, query_text=query_text, top_k=top_k, max_tokens=20000, score_threshold=0.04 +# ) +# pytest.assume(len(res) == top_k) +# for chunk in res: +# chunk_dict = vars(chunk) +# assume_query_chunk_result(query_text, chunk_dict) +# pytest.assume(chunk_dict["score"] >= 0.04) +# +# @pytest.mark.run(order=42) +# def test_create_chunk(self, collection_id): +# # Create a chunk. +# create_chunk_data = { +# "collection_id": collection_id, +# "content": "Machine learning is a subfield of artificial intelligence (AI) that involves the development of algorithms that allow computers to learn from and make decisions or predictions based on data.", +# } +# res = create_chunk(**create_chunk_data) +# res_dict = vars(res) +# assume_chunk_result(create_chunk_data, res_dict) +# +# @pytest.mark.run(order=43) +# def test_list_chunks(self, collection_id): +# # List chunks. +# +# nums_limit = 1 +# res = list_chunks(limit=nums_limit, collection_id=collection_id) +# pytest.assume(len(res) == nums_limit) +# +# after_id = res[-1].chunk_id +# after_res = list_chunks(limit=nums_limit, after=after_id, collection_id=collection_id) +# pytest.assume(len(after_res) == nums_limit) +# +# twice_nums_list = list_chunks(limit=nums_limit * 2, collection_id=collection_id) +# pytest.assume(len(twice_nums_list) == nums_limit * 2) +# pytest.assume(after_res[-1] == twice_nums_list[-1]) +# pytest.assume(after_res[0] == twice_nums_list[nums_limit]) +# +# before_id = after_res[0].chunk_id +# before_res = list_chunks(limit=nums_limit, before=before_id, collection_id=collection_id) +# pytest.assume(len(before_res) == nums_limit) +# pytest.assume(before_res[-1] == twice_nums_list[nums_limit - 1]) +# pytest.assume(before_res[0] == twice_nums_list[0]) +# +# @pytest.mark.run(order=44) +# def test_get_chunk(self, collection_id): +# # list chunks +# +# chunks = list_chunks(collection_id=collection_id) +# for chunk in chunks: +# chunk_id = chunk.chunk_id +# res = get_chunk(collection_id=collection_id, chunk_id=chunk_id) +# logger.info(f"get chunk response: {res}") +# res_dict = vars(res) +# pytest.assume(res_dict["collection_id"] == collection_id) +# pytest.assume(res_dict["chunk_id"] == chunk_id) +# +# @pytest.mark.run(order=45) +# def test_update_chunk(self, collection_id, chunk_id): +# # Update a chunk. +# +# update_chunk_data = { +# "collection_id": collection_id, +# "chunk_id": chunk_id, +# "content": "Machine learning is a subfield of artificial intelligence (AI) that involves the development of algorithms that allow computers to learn from and make decisions or predictions based on data.", +# "metadata": {"test": "test"}, +# } +# res = update_chunk(**update_chunk_data) +# res_dict = vars(res) +# assume_chunk_result(update_chunk_data, res_dict) +# +# @pytest.mark.run(order=46) +# def test_delete_chunk(self, collection_id): +# # List chunks. +# +# chunks = list_chunks(collection_id=collection_id, limit=5) +# for index, chunk in enumerate(chunks): +# chunk_id = chunk.chunk_id +# +# # Delete a chunk. +# +# delete_chunk(collection_id=collection_id, chunk_id=chunk_id) +# +# # List chunks. +# +# new_chunks = list_chunks(collection_id=collection_id) +# chunk_ids = [chunk.chunk_id for chunk in new_chunks] +# pytest.assume(chunk_id not in chunk_ids) From e2226f533209a947d4f2f04702c5829f13d5ca36 Mon Sep 17 00:00:00 2001 From: taskingaijc <150663083+taskingaijc@users.noreply.github.com> Date: Tue, 4 Jun 2024 17:21:25 +0800 Subject: [PATCH 10/13] test: add test --- .../test_async/test_async_retrieval.py | 92 +++++---- .../testcase/test_sync/test_sync_retrieval.py | 192 +++++++++--------- 2 files changed, 143 insertions(+), 141 deletions(-) diff --git a/test/testcase/test_async/test_async_retrieval.py b/test/testcase/test_async/test_async_retrieval.py index d06f9da..f2cecf9 100644 --- a/test/testcase/test_async/test_async_retrieval.py +++ b/test/testcase/test_async/test_async_retrieval.py @@ -231,51 +231,53 @@ async def test_a_update_record_by_text(self, text_splitter): assume_record_result(update_record_data, res_dict) records = list_records(collection_id=self.collection_id, order="desc", limit=20, after=None, before=None) - # @pytest.mark.run(order=34) - # @pytest.mark.asyncio - # @pytest.mark.parametrize("text_splitter", text_splitter_list) - # async def test_a_update_record_by_web(self, text_splitter): - # # Update a record. - # - # update_record_data = { - # "type": "web", - # "title": "Machine learning", - # "collection_id": self.collection_id, - # "record_id": self.record_id, - # "url": "https://docs.tasking.ai/docs/guide/getting_started/overview/", - # "text_splitter": text_splitter, - # "metadata": {"test": "test"}, - # } - # res = await a_update_record(**update_record_data) - # logger.info(f"a_update_record:{res}") - # res_dict = vars(res) - # assume_record_result(update_record_data, res_dict) - # - # @pytest.mark.run(order=34) - # @pytest.mark.asyncio - # @pytest.mark.parametrize("upload_file_data", upload_file_data_list[2:3]) - # async def test_a_update_record_by_file(self, upload_file_data): - # # upload file - # upload_file_res = await a_upload_file(**upload_file_data) - # upload_file_dict = vars(upload_file_res) - # file_id = upload_file_dict["file_id"] - # pytest.assume(file_id is not None) - # - # # Update a record. - # - # update_record_data = { - # "type": "file", - # "title": "Machine learning", - # "collection_id": self.collection_id, - # "record_id": self.record_id, - # "file_id": file_id, - # "text_splitter": TokenTextSplitter(chunk_size=200, chunk_overlap=100), - # "metadata": {"test": "test"}, - # } - # res = await a_update_record(**update_record_data) - # logger.info(f"a_update_record:{res}") - # res_dict = vars(res) - # assume_record_result(update_record_data, res_dict) + @pytest.mark.run(order=34) + @pytest.mark.asyncio + @pytest.mark.parametrize("text_splitter", text_splitter_list) + async def test_a_update_record_by_web(self, text_splitter): + # Update a record. + + update_record_data = { + "type": "web", + "title": "Machine learning", + "collection_id": self.collection_id, + "record_id": self.record_id, + "url": "https://docs.tasking.ai/docs/guide/getting_started/overview/", + "text_splitter": text_splitter, + "metadata": {"test": "test"}, + } + res = await a_update_record(**update_record_data) + logger.info(f"a_update_record:{res}") + res_dict = vars(res) + assume_record_result(update_record_data, res_dict) + records = list_records(collection_id=self.collection_id, order="desc", limit=20, after=None, before=None) + + @pytest.mark.run(order=34) + @pytest.mark.asyncio + @pytest.mark.parametrize("upload_file_data", upload_file_data_list[2:3]) + async def test_a_update_record_by_file(self, upload_file_data): + # upload file + upload_file_res = await a_upload_file(**upload_file_data) + upload_file_dict = vars(upload_file_res) + file_id = upload_file_dict["file_id"] + pytest.assume(file_id is not None) + + # Update a record. + + update_record_data = { + "type": "file", + "title": "Machine learning", + "collection_id": self.collection_id, + "record_id": self.record_id, + "file_id": file_id, + "text_splitter": TokenTextSplitter(chunk_size=200, chunk_overlap=100), + "metadata": {"test": "test"}, + } + res = await a_update_record(**update_record_data) + logger.info(f"a_update_record:{res}") + res_dict = vars(res) + assume_record_result(update_record_data, res_dict) + records = list_records(collection_id=self.collection_id, order="desc", limit=20, after=None, before=None) @pytest.mark.run(order=79) @pytest.mark.asyncio diff --git a/test/testcase/test_sync/test_sync_retrieval.py b/test/testcase/test_sync/test_sync_retrieval.py index 8795898..c7c4ba9 100644 --- a/test/testcase/test_sync/test_sync_retrieval.py +++ b/test/testcase/test_sync/test_sync_retrieval.py @@ -314,99 +314,99 @@ def test_delete_record(self, collection_id): pytest.assume(new_nums == 0) -# @pytest.mark.test_sync -# class TestChunk: -# -# @pytest.mark.run(order=41) -# def test_query_chunks(self, collection_id): -# # Query chunks. -# -# query_text = "Machine learning" -# top_k = 1 -# res = query_chunks( -# collection_id=collection_id, query_text=query_text, top_k=top_k, max_tokens=20000, score_threshold=0.04 -# ) -# pytest.assume(len(res) == top_k) -# for chunk in res: -# chunk_dict = vars(chunk) -# assume_query_chunk_result(query_text, chunk_dict) -# pytest.assume(chunk_dict["score"] >= 0.04) -# -# @pytest.mark.run(order=42) -# def test_create_chunk(self, collection_id): -# # Create a chunk. -# create_chunk_data = { -# "collection_id": collection_id, -# "content": "Machine learning is a subfield of artificial intelligence (AI) that involves the development of algorithms that allow computers to learn from and make decisions or predictions based on data.", -# } -# res = create_chunk(**create_chunk_data) -# res_dict = vars(res) -# assume_chunk_result(create_chunk_data, res_dict) -# -# @pytest.mark.run(order=43) -# def test_list_chunks(self, collection_id): -# # List chunks. -# -# nums_limit = 1 -# res = list_chunks(limit=nums_limit, collection_id=collection_id) -# pytest.assume(len(res) == nums_limit) -# -# after_id = res[-1].chunk_id -# after_res = list_chunks(limit=nums_limit, after=after_id, collection_id=collection_id) -# pytest.assume(len(after_res) == nums_limit) -# -# twice_nums_list = list_chunks(limit=nums_limit * 2, collection_id=collection_id) -# pytest.assume(len(twice_nums_list) == nums_limit * 2) -# pytest.assume(after_res[-1] == twice_nums_list[-1]) -# pytest.assume(after_res[0] == twice_nums_list[nums_limit]) -# -# before_id = after_res[0].chunk_id -# before_res = list_chunks(limit=nums_limit, before=before_id, collection_id=collection_id) -# pytest.assume(len(before_res) == nums_limit) -# pytest.assume(before_res[-1] == twice_nums_list[nums_limit - 1]) -# pytest.assume(before_res[0] == twice_nums_list[0]) -# -# @pytest.mark.run(order=44) -# def test_get_chunk(self, collection_id): -# # list chunks -# -# chunks = list_chunks(collection_id=collection_id) -# for chunk in chunks: -# chunk_id = chunk.chunk_id -# res = get_chunk(collection_id=collection_id, chunk_id=chunk_id) -# logger.info(f"get chunk response: {res}") -# res_dict = vars(res) -# pytest.assume(res_dict["collection_id"] == collection_id) -# pytest.assume(res_dict["chunk_id"] == chunk_id) -# -# @pytest.mark.run(order=45) -# def test_update_chunk(self, collection_id, chunk_id): -# # Update a chunk. -# -# update_chunk_data = { -# "collection_id": collection_id, -# "chunk_id": chunk_id, -# "content": "Machine learning is a subfield of artificial intelligence (AI) that involves the development of algorithms that allow computers to learn from and make decisions or predictions based on data.", -# "metadata": {"test": "test"}, -# } -# res = update_chunk(**update_chunk_data) -# res_dict = vars(res) -# assume_chunk_result(update_chunk_data, res_dict) -# -# @pytest.mark.run(order=46) -# def test_delete_chunk(self, collection_id): -# # List chunks. -# -# chunks = list_chunks(collection_id=collection_id, limit=5) -# for index, chunk in enumerate(chunks): -# chunk_id = chunk.chunk_id -# -# # Delete a chunk. -# -# delete_chunk(collection_id=collection_id, chunk_id=chunk_id) -# -# # List chunks. -# -# new_chunks = list_chunks(collection_id=collection_id) -# chunk_ids = [chunk.chunk_id for chunk in new_chunks] -# pytest.assume(chunk_id not in chunk_ids) +@pytest.mark.test_sync +class TestChunk: + + @pytest.mark.run(order=41) + def test_query_chunks(self, collection_id): + # Query chunks. + + query_text = "Machine learning" + top_k = 1 + res = query_chunks( + collection_id=collection_id, query_text=query_text, top_k=top_k, max_tokens=20000, score_threshold=0.04 + ) + pytest.assume(len(res) == top_k) + for chunk in res: + chunk_dict = vars(chunk) + assume_query_chunk_result(query_text, chunk_dict) + pytest.assume(chunk_dict["score"] >= 0.04) + + @pytest.mark.run(order=42) + def test_create_chunk(self, collection_id): + # Create a chunk. + create_chunk_data = { + "collection_id": collection_id, + "content": "Machine learning is a subfield of artificial intelligence (AI) that involves the development of algorithms that allow computers to learn from and make decisions or predictions based on data.", + } + res = create_chunk(**create_chunk_data) + res_dict = vars(res) + assume_chunk_result(create_chunk_data, res_dict) + + @pytest.mark.run(order=43) + def test_list_chunks(self, collection_id): + # List chunks. + + nums_limit = 1 + res = list_chunks(limit=nums_limit, collection_id=collection_id) + pytest.assume(len(res) == nums_limit) + + after_id = res[-1].chunk_id + after_res = list_chunks(limit=nums_limit, after=after_id, collection_id=collection_id) + pytest.assume(len(after_res) == nums_limit) + + twice_nums_list = list_chunks(limit=nums_limit * 2, collection_id=collection_id) + pytest.assume(len(twice_nums_list) == nums_limit * 2) + pytest.assume(after_res[-1] == twice_nums_list[-1]) + pytest.assume(after_res[0] == twice_nums_list[nums_limit]) + + before_id = after_res[0].chunk_id + before_res = list_chunks(limit=nums_limit, before=before_id, collection_id=collection_id) + pytest.assume(len(before_res) == nums_limit) + pytest.assume(before_res[-1] == twice_nums_list[nums_limit - 1]) + pytest.assume(before_res[0] == twice_nums_list[0]) + + @pytest.mark.run(order=44) + def test_get_chunk(self, collection_id): + # list chunks + + chunks = list_chunks(collection_id=collection_id) + for chunk in chunks: + chunk_id = chunk.chunk_id + res = get_chunk(collection_id=collection_id, chunk_id=chunk_id) + logger.info(f"get chunk response: {res}") + res_dict = vars(res) + pytest.assume(res_dict["collection_id"] == collection_id) + pytest.assume(res_dict["chunk_id"] == chunk_id) + + @pytest.mark.run(order=45) + def test_update_chunk(self, collection_id, chunk_id): + # Update a chunk. + + update_chunk_data = { + "collection_id": collection_id, + "chunk_id": chunk_id, + "content": "Machine learning is a subfield of artificial intelligence (AI) that involves the development of algorithms that allow computers to learn from and make decisions or predictions based on data.", + "metadata": {"test": "test"}, + } + res = update_chunk(**update_chunk_data) + res_dict = vars(res) + assume_chunk_result(update_chunk_data, res_dict) + + @pytest.mark.run(order=46) + def test_delete_chunk(self, collection_id): + # List chunks. + + chunks = list_chunks(collection_id=collection_id, limit=5) + for index, chunk in enumerate(chunks): + chunk_id = chunk.chunk_id + + # Delete a chunk. + + delete_chunk(collection_id=collection_id, chunk_id=chunk_id) + + # List chunks. + + new_chunks = list_chunks(collection_id=collection_id) + chunk_ids = [chunk.chunk_id for chunk in new_chunks] + pytest.assume(chunk_id not in chunk_ids) From 884436550952810c35bc776737313907c06a4d19 Mon Sep 17 00:00:00 2001 From: taskingaijc <150663083+taskingaijc@users.noreply.github.com> Date: Tue, 4 Jun 2024 17:23:56 +0800 Subject: [PATCH 11/13] test: add test --- test/testcase/test_sync/test_sync_retrieval.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/testcase/test_sync/test_sync_retrieval.py b/test/testcase/test_sync/test_sync_retrieval.py index c7c4ba9..65785d1 100644 --- a/test/testcase/test_sync/test_sync_retrieval.py +++ b/test/testcase/test_sync/test_sync_retrieval.py @@ -342,6 +342,8 @@ def test_create_chunk(self, collection_id): res = create_chunk(**create_chunk_data) res_dict = vars(res) assume_chunk_result(create_chunk_data, res_dict) + records = list_records(collection_id=collection_id, order="desc", limit=20, after=None, before=None) + @pytest.mark.run(order=43) def test_list_chunks(self, collection_id): @@ -392,6 +394,7 @@ def test_update_chunk(self, collection_id, chunk_id): res = update_chunk(**update_chunk_data) res_dict = vars(res) assume_chunk_result(update_chunk_data, res_dict) + records = list_records(collection_id=collection_id, order="desc", limit=20, after=None, before=None) @pytest.mark.run(order=46) def test_delete_chunk(self, collection_id): @@ -410,3 +413,4 @@ def test_delete_chunk(self, collection_id): new_chunks = list_chunks(collection_id=collection_id) chunk_ids = [chunk.chunk_id for chunk in new_chunks] pytest.assume(chunk_id not in chunk_ids) + records = list_records(collection_id=collection_id, order="desc", limit=20, after=None, before=None) From 3b08d41c1f3b326ce33056cab40fde3125a49848 Mon Sep 17 00:00:00 2001 From: taskingaijc <150663083+taskingaijc@users.noreply.github.com> Date: Tue, 4 Jun 2024 17:32:54 +0800 Subject: [PATCH 12/13] test: add test --- .../testcase/test_sync/test_sync_retrieval.py | 89 ++++++++++--------- 1 file changed, 47 insertions(+), 42 deletions(-) diff --git a/test/testcase/test_sync/test_sync_retrieval.py b/test/testcase/test_sync/test_sync_retrieval.py index 65785d1..531e7e9 100644 --- a/test/testcase/test_sync/test_sync_retrieval.py +++ b/test/testcase/test_sync/test_sync_retrieval.py @@ -248,50 +248,55 @@ def test_update_record_by_text(self, collection_id, record_id, text_splitter): res = update_record(**update_record_data) res_dict = vars(res) assume_record_result(update_record_data, res_dict) + time.sleep(2) records = list_records(collection_id=collection_id, order="desc", limit=20, after=None, before=None) - # @pytest.mark.run(order=34) - # @pytest.mark.parametrize("text_splitter", text_splitter_list) - # def test_update_record_by_web(self, collection_id, record_id, text_splitter): - # # Update a record. - # - # update_record_data = { - # "type": "web", - # "title": "TaskingAI", - # "collection_id": collection_id, - # "record_id": record_id, - # "url": "https://docs.tasking.ai/docs/guide/getting_started/overview/", - # "text_splitter": text_splitter, - # "metadata": {"test": "test"}, - # } - # res = update_record(**update_record_data) - # res_dict = vars(res) - # assume_record_result(update_record_data, res_dict) - # - # @pytest.mark.run(order=35) - # @pytest.mark.parametrize("upload_file_data", upload_file_data_list[2:3]) - # def test_update_record_by_file(self, collection_id, record_id, upload_file_data): - # # upload file - # upload_file_res = upload_file(**upload_file_data) - # upload_file_dict = vars(upload_file_res) - # file_id = upload_file_dict["file_id"] - # pytest.assume(file_id is not None) - # - # # Update a record. - # text_splitter = TokenTextSplitter(chunk_size=200, chunk_overlap=20) - # - # update_record_data = { - # "type": "file", - # "title": "TaskingAI", - # "collection_id": collection_id, - # "record_id": record_id, - # "file_id": file_id, - # "text_splitter": text_splitter, - # "metadata": {"test": "test"}, - # } - # res = update_record(**update_record_data) - # res_dict = vars(res) - # assume_record_result(update_record_data, res_dict) + @pytest.mark.run(order=34) + @pytest.mark.parametrize("text_splitter", text_splitter_list) + def test_update_record_by_web(self, collection_id, record_id, text_splitter): + # Update a record. + + update_record_data = { + "type": "web", + "title": "TaskingAI", + "collection_id": collection_id, + "record_id": record_id, + "url": "https://docs.tasking.ai/docs/guide/getting_started/overview/", + "text_splitter": text_splitter, + "metadata": {"test": "test"}, + } + res = update_record(**update_record_data) + res_dict = vars(res) + assume_record_result(update_record_data, res_dict) + time.sleep(2) + records = list_records(collection_id=collection_id, order="desc", limit=20, after=None, before=None) + + @pytest.mark.run(order=35) + @pytest.mark.parametrize("upload_file_data", upload_file_data_list[2:3]) + def test_update_record_by_file(self, collection_id, record_id, upload_file_data): + # upload file + upload_file_res = upload_file(**upload_file_data) + upload_file_dict = vars(upload_file_res) + file_id = upload_file_dict["file_id"] + pytest.assume(file_id is not None) + + # Update a record. + text_splitter = TokenTextSplitter(chunk_size=200, chunk_overlap=20) + + update_record_data = { + "type": "file", + "title": "TaskingAI", + "collection_id": collection_id, + "record_id": record_id, + "file_id": file_id, + "text_splitter": text_splitter, + "metadata": {"test": "test"}, + } + res = update_record(**update_record_data) + res_dict = vars(res) + assume_record_result(update_record_data, res_dict) + time.sleep(2) + records = list_records(collection_id=collection_id, order="desc", limit=20, after=None, before=None) @pytest.mark.run(order=79) def test_delete_record(self, collection_id): From 02e5791d412da69e70b3228b95de2c1b84546580 Mon Sep 17 00:00:00 2001 From: taskingaijc <150663083+taskingaijc@users.noreply.github.com> Date: Tue, 4 Jun 2024 17:52:02 +0800 Subject: [PATCH 13/13] test: add test --- .../testcase/test_sync/test_sync_retrieval.py | 47 +++++++++++-------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/test/testcase/test_sync/test_sync_retrieval.py b/test/testcase/test_sync/test_sync_retrieval.py index 531e7e9..7621212 100644 --- a/test/testcase/test_sync/test_sync_retrieval.py +++ b/test/testcase/test_sync/test_sync_retrieval.py @@ -248,8 +248,7 @@ def test_update_record_by_text(self, collection_id, record_id, text_splitter): res = update_record(**update_record_data) res_dict = vars(res) assume_record_result(update_record_data, res_dict) - time.sleep(2) - records = list_records(collection_id=collection_id, order="desc", limit=20, after=None, before=None) + @pytest.mark.run(order=34) @pytest.mark.parametrize("text_splitter", text_splitter_list) @@ -268,8 +267,7 @@ def test_update_record_by_web(self, collection_id, record_id, text_splitter): res = update_record(**update_record_data) res_dict = vars(res) assume_record_result(update_record_data, res_dict) - time.sleep(2) - records = list_records(collection_id=collection_id, order="desc", limit=20, after=None, before=None) + @pytest.mark.run(order=35) @pytest.mark.parametrize("upload_file_data", upload_file_data_list[2:3]) @@ -295,8 +293,7 @@ def test_update_record_by_file(self, collection_id, record_id, upload_file_data) res = update_record(**update_record_data) res_dict = vars(res) assume_record_result(update_record_data, res_dict) - time.sleep(2) - records = list_records(collection_id=collection_id, order="desc", limit=20, after=None, before=None) + @pytest.mark.run(order=79) def test_delete_record(self, collection_id): @@ -339,6 +336,7 @@ def test_query_chunks(self, collection_id): @pytest.mark.run(order=42) def test_create_chunk(self, collection_id): + time.sleep(2) # Create a chunk. create_chunk_data = { "collection_id": collection_id, @@ -399,23 +397,32 @@ def test_update_chunk(self, collection_id, chunk_id): res = update_chunk(**update_chunk_data) res_dict = vars(res) assume_chunk_result(update_chunk_data, res_dict) - records = list_records(collection_id=collection_id, order="desc", limit=20, after=None, before=None) + @pytest.mark.run(order=46) - def test_delete_chunk(self, collection_id): + def test_delete_chunk(self, collection_id, chunk_id): # List chunks. - chunks = list_chunks(collection_id=collection_id, limit=5) - for index, chunk in enumerate(chunks): - chunk_id = chunk.chunk_id - - # Delete a chunk. - - delete_chunk(collection_id=collection_id, chunk_id=chunk_id) + # chunks = list_chunks(collection_id=collection_id, limit=5) + # for index, chunk in enumerate(chunks): + # chunk_id = chunk.chunk_id + # + # # Delete a chunk. + # + # delete_chunk(collection_id=collection_id, chunk_id=chunk_id) + # + # # List chunks. + # + # new_chunks = list_chunks(collection_id=collection_id) + # chunk_ids = [chunk.chunk_id for chunk in new_chunks] + # pytest.assume(chunk_id not in chunk_ids) + # records = list_records(collection_id=collection_id, order="desc", limit=20, after=None, before=None) + # for record in records: + delete_chunk(collection_id=collection_id, chunk_id=chunk_id) - # List chunks. + # List chunks. - new_chunks = list_chunks(collection_id=collection_id) - chunk_ids = [chunk.chunk_id for chunk in new_chunks] - pytest.assume(chunk_id not in chunk_ids) - records = list_records(collection_id=collection_id, order="desc", limit=20, after=None, before=None) + new_chunks = list_chunks(collection_id=collection_id) + chunk_ids = [chunk.chunk_id for chunk in new_chunks] + pytest.assume(chunk_id not in chunk_ids) + records = list_records(collection_id=collection_id, order="desc", limit=20, after=None, before=None)