mirror of
https://git.mirrors.martin98.com/https://github.com/infiniflow/ragflow.git
synced 2025-04-19 04:30:01 +08:00
Test: Added test cases for Create Session With Chat Assistant HTTP API (#6902)
### What problem does this PR solve? cover [create session with chat assistant](https://ragflow.io/docs/dev/http_api_reference#create-session-with-chat-assistant) endpoints ### Type of change - [x] add test cases
This commit is contained in:
parent
9d9f2dacd2
commit
ae107f31d9
@ -28,11 +28,14 @@ FILE_API_URL = "/api/v1/datasets/{dataset_id}/documents"
|
|||||||
FILE_CHUNK_API_URL = "/api/v1/datasets/{dataset_id}/chunks"
|
FILE_CHUNK_API_URL = "/api/v1/datasets/{dataset_id}/chunks"
|
||||||
CHUNK_API_URL = "/api/v1/datasets/{dataset_id}/documents/{document_id}/chunks"
|
CHUNK_API_URL = "/api/v1/datasets/{dataset_id}/documents/{document_id}/chunks"
|
||||||
CHAT_ASSISTANT_API_URL = "/api/v1/chats"
|
CHAT_ASSISTANT_API_URL = "/api/v1/chats"
|
||||||
|
SESSION_WITH_CHAT_ASSISTANT_API_URL = "/api/v1/chats/{chat_id}/sessions"
|
||||||
|
SESSION_WITH_AGENT_API_URL = "/api/v1/agents/{agent_id}/sessions"
|
||||||
|
|
||||||
INVALID_API_TOKEN = "invalid_key_123"
|
INVALID_API_TOKEN = "invalid_key_123"
|
||||||
DATASET_NAME_LIMIT = 128
|
DATASET_NAME_LIMIT = 128
|
||||||
DOCUMENT_NAME_LIMIT = 128
|
DOCUMENT_NAME_LIMIT = 128
|
||||||
CHAT_ASSISTANT_LIMIT = 255
|
CHAT_ASSISTANT_NAME_LIMIT = 255
|
||||||
|
SESSION_WITH_CHAT_NAME_LIMIT = 255
|
||||||
|
|
||||||
|
|
||||||
# DATASET MANAGEMENT
|
# DATASET MANAGEMENT
|
||||||
@ -219,3 +222,28 @@ def batch_create_chat_assistants(auth, num):
|
|||||||
res = create_chat_assistant(auth, {"name": f"test_chat_assistant_{i}", "dataset_ids": []})
|
res = create_chat_assistant(auth, {"name": f"test_chat_assistant_{i}", "dataset_ids": []})
|
||||||
chat_assistant_ids.append(res["data"]["id"])
|
chat_assistant_ids.append(res["data"]["id"])
|
||||||
return chat_assistant_ids
|
return chat_assistant_ids
|
||||||
|
|
||||||
|
|
||||||
|
# SESSION MANAGEMENT
|
||||||
|
def create_session_with_chat_assistant(auth, chat_assistant_id, payload=None):
|
||||||
|
url = f"{HOST_ADDRESS}{SESSION_WITH_CHAT_ASSISTANT_API_URL}".format(chat_id=chat_assistant_id)
|
||||||
|
res = requests.post(url=url, headers=HEADERS, auth=auth, json=payload)
|
||||||
|
return res.json()
|
||||||
|
|
||||||
|
|
||||||
|
def list_session_with_chat_assistants(auth, chat_assistant_id, params=None):
|
||||||
|
url = f"{HOST_ADDRESS}{SESSION_WITH_CHAT_ASSISTANT_API_URL}".format(chat_id=chat_assistant_id)
|
||||||
|
res = requests.get(url=url, headers=HEADERS, auth=auth, params=params)
|
||||||
|
return res.json()
|
||||||
|
|
||||||
|
|
||||||
|
def update_session_with_chat_assistant(auth, chat_assistant_id, session_id, payload=None):
|
||||||
|
url = f"{HOST_ADDRESS}{SESSION_WITH_CHAT_ASSISTANT_API_URL}/{session_id}".format(chat_id=chat_assistant_id)
|
||||||
|
res = requests.put(url=url, headers=HEADERS, auth=auth, json=payload)
|
||||||
|
return res.json()
|
||||||
|
|
||||||
|
|
||||||
|
def delete_session_with_chat_assistants(auth, chat_assistant_id, payload=None):
|
||||||
|
url = f"{HOST_ADDRESS}{SESSION_WITH_CHAT_ASSISTANT_API_URL}".format(chat_id=chat_assistant_id)
|
||||||
|
res = requests.delete(url=url, headers=HEADERS, auth=auth, json=payload)
|
||||||
|
return res.json()
|
||||||
|
@ -15,7 +15,17 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from common import add_chunk, batch_create_datasets, bulk_upload_documents, delete_chat_assistants, delete_datasets, list_documnets, parse_documnets
|
from common import (
|
||||||
|
add_chunk,
|
||||||
|
batch_create_datasets,
|
||||||
|
bulk_upload_documents,
|
||||||
|
create_chat_assistant,
|
||||||
|
delete_chat_assistants,
|
||||||
|
delete_datasets,
|
||||||
|
delete_session_with_chat_assistants,
|
||||||
|
list_documnets,
|
||||||
|
parse_documnets,
|
||||||
|
)
|
||||||
from libs.utils import wait_for
|
from libs.utils import wait_for
|
||||||
from libs.utils.file_utils import (
|
from libs.utils.file_utils import (
|
||||||
create_docx_file,
|
create_docx_file,
|
||||||
@ -41,15 +51,30 @@ def condition(_auth, _dataset_id):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="function")
|
@pytest.fixture(scope="function")
|
||||||
def clear_datasets(get_http_api_auth):
|
def clear_datasets(request, get_http_api_auth):
|
||||||
yield
|
def cleanup():
|
||||||
delete_datasets(get_http_api_auth)
|
delete_datasets(get_http_api_auth)
|
||||||
|
|
||||||
|
request.addfinalizer(cleanup)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="function")
|
@pytest.fixture(scope="function")
|
||||||
def clear_chat_assistants(get_http_api_auth):
|
def clear_chat_assistants(request, get_http_api_auth):
|
||||||
yield
|
def cleanup():
|
||||||
delete_chat_assistants(get_http_api_auth)
|
delete_chat_assistants(get_http_api_auth)
|
||||||
|
|
||||||
|
request.addfinalizer(cleanup)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="function")
|
||||||
|
def clear_session_with_chat_assistants(request, get_http_api_auth, add_chat_assistants):
|
||||||
|
_, _, chat_assistant_ids = add_chat_assistants
|
||||||
|
|
||||||
|
def cleanup():
|
||||||
|
for chat_assistant_id in chat_assistant_ids:
|
||||||
|
delete_session_with_chat_assistants(get_http_api_auth, chat_assistant_id)
|
||||||
|
|
||||||
|
request.addfinalizer(cleanup)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
@ -126,3 +151,22 @@ def add_chunks(get_http_api_auth, add_document):
|
|||||||
|
|
||||||
sleep(1)
|
sleep(1)
|
||||||
return dataset_id, document_id, chunk_ids
|
return dataset_id, document_id, chunk_ids
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="class")
|
||||||
|
def add_chat_assistants(request, get_http_api_auth, add_document):
|
||||||
|
def cleanup():
|
||||||
|
delete_chat_assistants(get_http_api_auth)
|
||||||
|
|
||||||
|
request.addfinalizer(cleanup)
|
||||||
|
|
||||||
|
dataset_id, document_id = add_document
|
||||||
|
parse_documnets(get_http_api_auth, dataset_id, {"document_ids": [document_id]})
|
||||||
|
condition(get_http_api_auth, dataset_id)
|
||||||
|
|
||||||
|
chat_assistant_ids = []
|
||||||
|
for i in range(5):
|
||||||
|
res = create_chat_assistant(get_http_api_auth, {"name": f"test_chat_assistant_{i}", "dataset_ids": [dataset_id]})
|
||||||
|
chat_assistant_ids.append(res["data"]["id"])
|
||||||
|
|
||||||
|
return dataset_id, document_id, chat_assistant_ids
|
||||||
|
@ -14,36 +14,33 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
import pytest
|
import pytest
|
||||||
from common import create_chat_assistant, delete_chat_assistants
|
from common import create_chat_assistant, delete_chat_assistants, list_documnets, parse_documnets
|
||||||
|
from libs.utils import wait_for
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="class")
|
@wait_for(30, 1, "Document parsing timeout")
|
||||||
def add_chat_assistants(request, get_http_api_auth, add_chunks):
|
def condition(_auth, _dataset_id):
|
||||||
def cleanup():
|
res = list_documnets(_auth, _dataset_id)
|
||||||
delete_chat_assistants(get_http_api_auth)
|
for doc in res["data"]["docs"]:
|
||||||
|
if doc["run"] != "DONE":
|
||||||
request.addfinalizer(cleanup)
|
return False
|
||||||
|
return True
|
||||||
dataset_id, document_id, chunk_ids = add_chunks
|
|
||||||
chat_assistant_ids = []
|
|
||||||
for i in range(5):
|
|
||||||
res = create_chat_assistant(get_http_api_auth, {"name": f"test_chat_assistant_{i}", "dataset_ids": [dataset_id]})
|
|
||||||
chat_assistant_ids.append(res["data"]["id"])
|
|
||||||
|
|
||||||
return dataset_id, document_id, chunk_ids, chat_assistant_ids
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="function")
|
@pytest.fixture(scope="function")
|
||||||
def add_chat_assistants_func(request, get_http_api_auth, add_chunks):
|
def add_chat_assistants_func(request, get_http_api_auth, add_document):
|
||||||
def cleanup():
|
def cleanup():
|
||||||
delete_chat_assistants(get_http_api_auth)
|
delete_chat_assistants(get_http_api_auth)
|
||||||
|
|
||||||
request.addfinalizer(cleanup)
|
request.addfinalizer(cleanup)
|
||||||
|
|
||||||
dataset_id, document_id, chunk_ids = add_chunks
|
dataset_id, document_id = add_document
|
||||||
|
parse_documnets(get_http_api_auth, dataset_id, {"document_ids": [document_id]})
|
||||||
|
condition(get_http_api_auth, dataset_id)
|
||||||
|
|
||||||
chat_assistant_ids = []
|
chat_assistant_ids = []
|
||||||
for i in range(5):
|
for i in range(5):
|
||||||
res = create_chat_assistant(get_http_api_auth, {"name": f"test_chat_assistant_{i}", "dataset_ids": [dataset_id]})
|
res = create_chat_assistant(get_http_api_auth, {"name": f"test_chat_assistant_{i}", "dataset_ids": [dataset_id]})
|
||||||
chat_assistant_ids.append(res["data"]["id"])
|
chat_assistant_ids.append(res["data"]["id"])
|
||||||
|
|
||||||
return dataset_id, document_id, chunk_ids, chat_assistant_ids
|
return dataset_id, document_id, chat_assistant_ids
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from common import CHAT_ASSISTANT_LIMIT, INVALID_API_TOKEN, create_chat_assistant
|
from common import CHAT_ASSISTANT_NAME_LIMIT, INVALID_API_TOKEN, create_chat_assistant
|
||||||
from libs.auth import RAGFlowHttpApiAuth
|
from libs.auth import RAGFlowHttpApiAuth
|
||||||
from libs.utils import encode_avatar
|
from libs.utils import encode_avatar
|
||||||
from libs.utils.file_utils import create_image_file
|
from libs.utils.file_utils import create_image_file
|
||||||
@ -46,7 +46,7 @@ class TestChatAssistantCreate:
|
|||||||
"payload, expected_code, expected_message",
|
"payload, expected_code, expected_message",
|
||||||
[
|
[
|
||||||
({"name": "valid_name"}, 0, ""),
|
({"name": "valid_name"}, 0, ""),
|
||||||
pytest.param({"name": "a" * (CHAT_ASSISTANT_LIMIT + 1)}, 102, "", marks=pytest.mark.skip(reason="issues/")),
|
pytest.param({"name": "a" * (CHAT_ASSISTANT_NAME_LIMIT + 1)}, 102, "", marks=pytest.mark.skip(reason="issues/")),
|
||||||
pytest.param({"name": 1}, 100, "", marks=pytest.mark.skip(reason="issues/")),
|
pytest.param({"name": 1}, 100, "", marks=pytest.mark.skip(reason="issues/")),
|
||||||
({"name": ""}, 102, "`name` is required."),
|
({"name": ""}, 102, "`name` is required."),
|
||||||
({"name": "duplicated_name"}, 102, "Duplicated chat name in creating chat."),
|
({"name": "duplicated_name"}, 102, "Duplicated chat name in creating chat."),
|
||||||
|
@ -52,7 +52,7 @@ class TestChatAssistantsDelete:
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_basic_scenarios(self, get_http_api_auth, add_chat_assistants_func, payload, expected_code, expected_message, remaining):
|
def test_basic_scenarios(self, get_http_api_auth, add_chat_assistants_func, payload, expected_code, expected_message, remaining):
|
||||||
_, _, _, chat_assistant_ids = add_chat_assistants_func
|
_, _, chat_assistant_ids = add_chat_assistants_func
|
||||||
if callable(payload):
|
if callable(payload):
|
||||||
payload = payload(chat_assistant_ids)
|
payload = payload(chat_assistant_ids)
|
||||||
res = delete_chat_assistants(get_http_api_auth, payload)
|
res = delete_chat_assistants(get_http_api_auth, payload)
|
||||||
@ -73,7 +73,7 @@ class TestChatAssistantsDelete:
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_delete_partial_invalid_id(self, get_http_api_auth, add_chat_assistants_func, payload):
|
def test_delete_partial_invalid_id(self, get_http_api_auth, add_chat_assistants_func, payload):
|
||||||
_, _, _, chat_assistant_ids = add_chat_assistants_func
|
_, _, chat_assistant_ids = add_chat_assistants_func
|
||||||
if callable(payload):
|
if callable(payload):
|
||||||
payload = payload(chat_assistant_ids)
|
payload = payload(chat_assistant_ids)
|
||||||
res = delete_chat_assistants(get_http_api_auth, payload)
|
res = delete_chat_assistants(get_http_api_auth, payload)
|
||||||
@ -85,7 +85,7 @@ class TestChatAssistantsDelete:
|
|||||||
assert len(res["data"]) == 0
|
assert len(res["data"]) == 0
|
||||||
|
|
||||||
def test_repeated_deletion(self, get_http_api_auth, add_chat_assistants_func):
|
def test_repeated_deletion(self, get_http_api_auth, add_chat_assistants_func):
|
||||||
_, _, _, chat_assistant_ids = add_chat_assistants_func
|
_, _, chat_assistant_ids = add_chat_assistants_func
|
||||||
res = delete_chat_assistants(get_http_api_auth, {"ids": chat_assistant_ids})
|
res = delete_chat_assistants(get_http_api_auth, {"ids": chat_assistant_ids})
|
||||||
assert res["code"] == 0
|
assert res["code"] == 0
|
||||||
|
|
||||||
@ -95,7 +95,7 @@ class TestChatAssistantsDelete:
|
|||||||
|
|
||||||
@pytest.mark.skip(reason="issues/6876")
|
@pytest.mark.skip(reason="issues/6876")
|
||||||
def test_duplicate_deletion(self, get_http_api_auth, add_chat_assistants_func):
|
def test_duplicate_deletion(self, get_http_api_auth, add_chat_assistants_func):
|
||||||
_, _, _, chat_assistant_ids = add_chat_assistants_func
|
_, _, chat_assistant_ids = add_chat_assistants_func
|
||||||
res = delete_chat_assistants(get_http_api_auth, {"ids": chat_assistant_ids + chat_assistant_ids})
|
res = delete_chat_assistants(get_http_api_auth, {"ids": chat_assistant_ids + chat_assistant_ids})
|
||||||
print(res)
|
print(res)
|
||||||
assert res["code"] == 0
|
assert res["code"] == 0
|
||||||
@ -105,6 +105,7 @@ class TestChatAssistantsDelete:
|
|||||||
res = delete_chat_assistants(get_http_api_auth)
|
res = delete_chat_assistants(get_http_api_auth)
|
||||||
assert len(res["data"]) == 0
|
assert len(res["data"]) == 0
|
||||||
|
|
||||||
|
@pytest.mark.slow
|
||||||
def test_concurrent_deletion(self, get_http_api_auth):
|
def test_concurrent_deletion(self, get_http_api_auth):
|
||||||
ids = batch_create_chat_assistants(get_http_api_auth, 100)
|
ids = batch_create_chat_assistants(get_http_api_auth, 100)
|
||||||
|
|
||||||
|
@ -288,7 +288,7 @@ class TestChatAssistantsList:
|
|||||||
expected_num,
|
expected_num,
|
||||||
expected_message,
|
expected_message,
|
||||||
):
|
):
|
||||||
_, _, _, chat_assistant_ids = add_chat_assistants
|
_, _, chat_assistant_ids = add_chat_assistants
|
||||||
if callable(chat_assistant_id):
|
if callable(chat_assistant_id):
|
||||||
params = {"id": chat_assistant_id(chat_assistant_ids)}
|
params = {"id": chat_assistant_id(chat_assistant_ids)}
|
||||||
else:
|
else:
|
||||||
@ -323,7 +323,7 @@ class TestChatAssistantsList:
|
|||||||
expected_num,
|
expected_num,
|
||||||
expected_message,
|
expected_message,
|
||||||
):
|
):
|
||||||
_, _, _, chat_assistant_ids = add_chat_assistants
|
_, _, chat_assistant_ids = add_chat_assistants
|
||||||
if callable(chat_assistant_id):
|
if callable(chat_assistant_id):
|
||||||
params = {"id": chat_assistant_id(chat_assistant_ids), "name": name}
|
params = {"id": chat_assistant_id(chat_assistant_ids), "name": name}
|
||||||
else:
|
else:
|
||||||
@ -336,6 +336,7 @@ class TestChatAssistantsList:
|
|||||||
else:
|
else:
|
||||||
assert res["message"] == expected_message
|
assert res["message"] == expected_message
|
||||||
|
|
||||||
|
@pytest.mark.slow
|
||||||
def test_concurrent_list(self, get_http_api_auth):
|
def test_concurrent_list(self, get_http_api_auth):
|
||||||
with ThreadPoolExecutor(max_workers=5) as executor:
|
with ThreadPoolExecutor(max_workers=5) as executor:
|
||||||
futures = [executor.submit(list_chat_assistants, get_http_api_auth) for i in range(100)]
|
futures = [executor.submit(list_chat_assistants, get_http_api_auth) for i in range(100)]
|
||||||
@ -349,7 +350,7 @@ class TestChatAssistantsList:
|
|||||||
assert len(res["data"]) == 5
|
assert len(res["data"]) == 5
|
||||||
|
|
||||||
def test_list_chats_after_deleting_associated_dataset(self, get_http_api_auth, add_chat_assistants):
|
def test_list_chats_after_deleting_associated_dataset(self, get_http_api_auth, add_chat_assistants):
|
||||||
dataset_id, _, _, _ = add_chat_assistants
|
dataset_id, _, _ = add_chat_assistants
|
||||||
res = delete_datasets(get_http_api_auth, {"ids": [dataset_id]})
|
res = delete_datasets(get_http_api_auth, {"ids": [dataset_id]})
|
||||||
assert res["code"] == 0
|
assert res["code"] == 0
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
import pytest
|
import pytest
|
||||||
from common import CHAT_ASSISTANT_LIMIT, INVALID_API_TOKEN, list_chat_assistants, update_chat_assistant
|
from common import CHAT_ASSISTANT_NAME_LIMIT, INVALID_API_TOKEN, list_chat_assistants, update_chat_assistant
|
||||||
from libs.auth import RAGFlowHttpApiAuth
|
from libs.auth import RAGFlowHttpApiAuth
|
||||||
from libs.utils import encode_avatar
|
from libs.utils import encode_avatar
|
||||||
from libs.utils.file_utils import create_image_file
|
from libs.utils.file_utils import create_image_file
|
||||||
@ -44,7 +44,7 @@ class TestChatAssistantUpdate:
|
|||||||
"payload, expected_code, expected_message",
|
"payload, expected_code, expected_message",
|
||||||
[
|
[
|
||||||
({"name": "valid_name"}, 0, ""),
|
({"name": "valid_name"}, 0, ""),
|
||||||
pytest.param({"name": "a" * (CHAT_ASSISTANT_LIMIT + 1)}, 102, "", marks=pytest.mark.skip(reason="issues/")),
|
pytest.param({"name": "a" * (CHAT_ASSISTANT_NAME_LIMIT + 1)}, 102, "", marks=pytest.mark.skip(reason="issues/")),
|
||||||
pytest.param({"name": 1}, 100, "", marks=pytest.mark.skip(reason="issues/")),
|
pytest.param({"name": 1}, 100, "", marks=pytest.mark.skip(reason="issues/")),
|
||||||
({"name": ""}, 102, "`name` cannot be empty."),
|
({"name": ""}, 102, "`name` cannot be empty."),
|
||||||
({"name": "test_chat_assistant_1"}, 102, "Duplicated chat name in updating chat."),
|
({"name": "test_chat_assistant_1"}, 102, "Duplicated chat name in updating chat."),
|
||||||
@ -52,7 +52,7 @@ class TestChatAssistantUpdate:
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_name(self, get_http_api_auth, add_chat_assistants_func, payload, expected_code, expected_message):
|
def test_name(self, get_http_api_auth, add_chat_assistants_func, payload, expected_code, expected_message):
|
||||||
_, _, _, chat_assistant_ids = add_chat_assistants_func
|
_, _, chat_assistant_ids = add_chat_assistants_func
|
||||||
|
|
||||||
res = update_chat_assistant(get_http_api_auth, chat_assistant_ids[0], payload)
|
res = update_chat_assistant(get_http_api_auth, chat_assistant_ids[0], payload)
|
||||||
assert res["code"] == expected_code, res
|
assert res["code"] == expected_code, res
|
||||||
@ -72,7 +72,7 @@ class TestChatAssistantUpdate:
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_dataset_ids(self, get_http_api_auth, add_chat_assistants_func, dataset_ids, expected_code, expected_message):
|
def test_dataset_ids(self, get_http_api_auth, add_chat_assistants_func, dataset_ids, expected_code, expected_message):
|
||||||
dataset_id, _, _, chat_assistant_ids = add_chat_assistants_func
|
dataset_id, _, chat_assistant_ids = add_chat_assistants_func
|
||||||
payload = {"name": "ragflow test"}
|
payload = {"name": "ragflow test"}
|
||||||
if callable(dataset_ids):
|
if callable(dataset_ids):
|
||||||
payload["dataset_ids"] = dataset_ids(dataset_id)
|
payload["dataset_ids"] = dataset_ids(dataset_id)
|
||||||
@ -88,7 +88,7 @@ class TestChatAssistantUpdate:
|
|||||||
assert res["message"] == expected_message
|
assert res["message"] == expected_message
|
||||||
|
|
||||||
def test_avatar(self, get_http_api_auth, add_chat_assistants_func, tmp_path):
|
def test_avatar(self, get_http_api_auth, add_chat_assistants_func, tmp_path):
|
||||||
dataset_id, _, _, chat_assistant_ids = add_chat_assistants_func
|
dataset_id, _, chat_assistant_ids = add_chat_assistants_func
|
||||||
fn = create_image_file(tmp_path / "ragflow_test.png")
|
fn = create_image_file(tmp_path / "ragflow_test.png")
|
||||||
payload = {"name": "avatar_test", "avatar": encode_avatar(fn), "dataset_ids": [dataset_id]}
|
payload = {"name": "avatar_test", "avatar": encode_avatar(fn), "dataset_ids": [dataset_id]}
|
||||||
res = update_chat_assistant(get_http_api_auth, chat_assistant_ids[0], payload)
|
res = update_chat_assistant(get_http_api_auth, chat_assistant_ids[0], payload)
|
||||||
@ -129,7 +129,7 @@ class TestChatAssistantUpdate:
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_llm(self, get_http_api_auth, add_chat_assistants_func, llm, expected_code, expected_message):
|
def test_llm(self, get_http_api_auth, add_chat_assistants_func, llm, expected_code, expected_message):
|
||||||
dataset_id, _, _, chat_assistant_ids = add_chat_assistants_func
|
dataset_id, _, chat_assistant_ids = add_chat_assistants_func
|
||||||
payload = {"name": "llm_test", "dataset_ids": [dataset_id], "llm": llm}
|
payload = {"name": "llm_test", "dataset_ids": [dataset_id], "llm": llm}
|
||||||
res = update_chat_assistant(get_http_api_auth, chat_assistant_ids[0], payload)
|
res = update_chat_assistant(get_http_api_auth, chat_assistant_ids[0], payload)
|
||||||
assert res["code"] == expected_code
|
assert res["code"] == expected_code
|
||||||
@ -196,7 +196,7 @@ class TestChatAssistantUpdate:
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_prompt(self, get_http_api_auth, add_chat_assistants_func, prompt, expected_code, expected_message):
|
def test_prompt(self, get_http_api_auth, add_chat_assistants_func, prompt, expected_code, expected_message):
|
||||||
dataset_id, _, _, chat_assistant_ids = add_chat_assistants_func
|
dataset_id, _, chat_assistant_ids = add_chat_assistants_func
|
||||||
payload = {"name": "prompt_test", "dataset_ids": [dataset_id], "prompt": prompt}
|
payload = {"name": "prompt_test", "dataset_ids": [dataset_id], "prompt": prompt}
|
||||||
res = update_chat_assistant(get_http_api_auth, chat_assistant_ids[0], payload)
|
res = update_chat_assistant(get_http_api_auth, chat_assistant_ids[0], payload)
|
||||||
assert res["code"] == expected_code
|
assert res["code"] == expected_code
|
||||||
|
@ -214,6 +214,7 @@ class TestAddChunk:
|
|||||||
assert res["code"] == 102
|
assert res["code"] == 102
|
||||||
assert res["message"] == f"You don't own the document {document_id}."
|
assert res["message"] == f"You don't own the document {document_id}."
|
||||||
|
|
||||||
|
@pytest.mark.slow
|
||||||
@pytest.mark.skip(reason="issues/6411")
|
@pytest.mark.skip(reason="issues/6411")
|
||||||
def test_concurrent_add_chunk(self, get_http_api_auth, add_document):
|
def test_concurrent_add_chunk(self, get_http_api_auth, add_document):
|
||||||
chunk_num = 50
|
chunk_num = 50
|
||||||
|
@ -291,6 +291,7 @@ class TestChunksRetrieval:
|
|||||||
assert res["code"] == 0
|
assert res["code"] == 0
|
||||||
assert len(res["data"]["chunks"]) == 4
|
assert len(res["data"]["chunks"]) == 4
|
||||||
|
|
||||||
|
@pytest.mark.slow
|
||||||
def test_concurrent_retrieval(self, get_http_api_auth, add_chunks):
|
def test_concurrent_retrieval(self, get_http_api_auth, add_chunks):
|
||||||
from concurrent.futures import ThreadPoolExecutor
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
|
|
||||||
|
@ -206,6 +206,7 @@ class TestUpdatedChunk:
|
|||||||
if expected_code != 0:
|
if expected_code != 0:
|
||||||
assert res["message"] == expected_message
|
assert res["message"] == expected_message
|
||||||
|
|
||||||
|
@pytest.mark.slow
|
||||||
@pytest.mark.skipif(os.getenv("DOC_ENGINE") == "infinity", reason="issues/6554")
|
@pytest.mark.skipif(os.getenv("DOC_ENGINE") == "infinity", reason="issues/6554")
|
||||||
def test_concurrent_update_chunk(self, get_http_api_auth, add_chunks):
|
def test_concurrent_update_chunk(self, get_http_api_auth, add_chunks):
|
||||||
chunk_num = 50
|
chunk_num = 50
|
||||||
|
@ -117,6 +117,7 @@ class TestDatasetsDeletion:
|
|||||||
res = list_datasets(get_http_api_auth)
|
res = list_datasets(get_http_api_auth)
|
||||||
assert len(res["data"]) == 0
|
assert len(res["data"]) == 0
|
||||||
|
|
||||||
|
@pytest.mark.slow
|
||||||
def test_concurrent_deletion(self, get_http_api_auth):
|
def test_concurrent_deletion(self, get_http_api_auth):
|
||||||
ids = batch_create_datasets(get_http_api_auth, 100)
|
ids = batch_create_datasets(get_http_api_auth, 100)
|
||||||
|
|
||||||
|
@ -337,6 +337,7 @@ class TestDatasetsList:
|
|||||||
else:
|
else:
|
||||||
assert res["message"] == expected_message
|
assert res["message"] == expected_message
|
||||||
|
|
||||||
|
@pytest.mark.slow
|
||||||
def test_concurrent_list(self, get_http_api_auth):
|
def test_concurrent_list(self, get_http_api_auth):
|
||||||
with ThreadPoolExecutor(max_workers=5) as executor:
|
with ThreadPoolExecutor(max_workers=5) as executor:
|
||||||
futures = [executor.submit(list_datasets, get_http_api_auth) for i in range(100)]
|
futures = [executor.submit(list_datasets, get_http_api_auth) for i in range(100)]
|
||||||
|
@ -236,6 +236,7 @@ class TestDatasetUpdate:
|
|||||||
res = update_dataset(get_http_api_auth, dataset_id, {"unknown_field": 0})
|
res = update_dataset(get_http_api_auth, dataset_id, {"unknown_field": 0})
|
||||||
assert res["code"] == 100
|
assert res["code"] == 100
|
||||||
|
|
||||||
|
@pytest.mark.slow
|
||||||
def test_concurrent_update(self, get_http_api_auth, add_dataset_func):
|
def test_concurrent_update(self, get_http_api_auth, add_dataset_func):
|
||||||
dataset_id = add_dataset_func
|
dataset_id = add_dataset_func
|
||||||
|
|
||||||
|
@ -140,6 +140,7 @@ class TestDocumentsDeletion:
|
|||||||
assert res["data"]["total"] == 0
|
assert res["data"]["total"] == 0
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.slow
|
||||||
def test_concurrent_deletion(get_http_api_auth, add_dataset, tmp_path):
|
def test_concurrent_deletion(get_http_api_auth, add_dataset, tmp_path):
|
||||||
documnets_num = 100
|
documnets_num = 100
|
||||||
dataset_id = add_dataset
|
dataset_id = add_dataset
|
||||||
|
@ -147,6 +147,7 @@ class TestDocumentDownload:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.slow
|
||||||
def test_concurrent_download(get_http_api_auth, add_dataset, tmp_path):
|
def test_concurrent_download(get_http_api_auth, add_dataset, tmp_path):
|
||||||
document_count = 20
|
document_count = 20
|
||||||
dataset_id = add_dataset
|
dataset_id = add_dataset
|
||||||
|
@ -406,6 +406,7 @@ class TestDocumentsList:
|
|||||||
else:
|
else:
|
||||||
assert res["message"] == expected_message
|
assert res["message"] == expected_message
|
||||||
|
|
||||||
|
@pytest.mark.slow
|
||||||
def test_concurrent_list(self, get_http_api_auth, add_documents):
|
def test_concurrent_list(self, get_http_api_auth, add_documents):
|
||||||
dataset_id, _ = add_documents
|
dataset_id, _ = add_documents
|
||||||
|
|
||||||
|
@ -186,6 +186,7 @@ class TestDocumentsUpload:
|
|||||||
res = list_datasets(get_http_api_auth, {"id": dataset_id})
|
res = list_datasets(get_http_api_auth, {"id": dataset_id})
|
||||||
assert res["data"][0]["document_count"] == expected_document_count
|
assert res["data"][0]["document_count"] == expected_document_count
|
||||||
|
|
||||||
|
@pytest.mark.slow
|
||||||
def test_concurrent_upload(self, get_http_api_auth, add_dataset_func, tmp_path):
|
def test_concurrent_upload(self, get_http_api_auth, add_dataset_func, tmp_path):
|
||||||
dataset_id = add_dataset_func
|
dataset_id = add_dataset_func
|
||||||
|
|
||||||
|
@ -0,0 +1,114 @@
|
|||||||
|
#
|
||||||
|
# Copyright 2025 The InfiniFlow Authors. All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from common import INVALID_API_TOKEN, SESSION_WITH_CHAT_NAME_LIMIT, create_session_with_chat_assistant, delete_chat_assistants, list_session_with_chat_assistants
|
||||||
|
from libs.auth import RAGFlowHttpApiAuth
|
||||||
|
|
||||||
|
|
||||||
|
class TestAuthorization:
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"auth, expected_code, expected_message",
|
||||||
|
[
|
||||||
|
(None, 0, "`Authorization` can't be empty"),
|
||||||
|
(
|
||||||
|
RAGFlowHttpApiAuth(INVALID_API_TOKEN),
|
||||||
|
109,
|
||||||
|
"Authentication error: API key is invalid!",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_invalid_auth(self, auth, expected_code, expected_message):
|
||||||
|
res = create_session_with_chat_assistant(auth, "chat_assistant_id")
|
||||||
|
assert res["code"] == expected_code
|
||||||
|
assert res["message"] == expected_message
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.usefixtures("clear_session_with_chat_assistants")
|
||||||
|
class TestSessionWithChatAssistantCreate:
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"payload, expected_code, expected_message",
|
||||||
|
[
|
||||||
|
({"name": "valid_name"}, 0, ""),
|
||||||
|
pytest.param({"name": "a" * (SESSION_WITH_CHAT_NAME_LIMIT + 1)}, 102, "", marks=pytest.mark.skip(reason="issues/")),
|
||||||
|
pytest.param({"name": 1}, 100, "", marks=pytest.mark.skip(reason="issues/")),
|
||||||
|
({"name": ""}, 102, "`name` can not be empty."),
|
||||||
|
({"name": "duplicated_name"}, 0, ""),
|
||||||
|
({"name": "case insensitive"}, 0, ""),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_name(self, get_http_api_auth, add_chat_assistants, payload, expected_code, expected_message):
|
||||||
|
_, _, chat_assistant_ids = add_chat_assistants
|
||||||
|
if payload["name"] == "duplicated_name":
|
||||||
|
create_session_with_chat_assistant(get_http_api_auth, chat_assistant_ids[0], payload)
|
||||||
|
elif payload["name"] == "case insensitive":
|
||||||
|
create_session_with_chat_assistant(get_http_api_auth, chat_assistant_ids[0], {"name": payload["name"].upper()})
|
||||||
|
|
||||||
|
res = create_session_with_chat_assistant(get_http_api_auth, chat_assistant_ids[0], payload)
|
||||||
|
assert res["code"] == expected_code, res
|
||||||
|
if expected_code == 0:
|
||||||
|
assert res["data"]["name"] == payload["name"]
|
||||||
|
assert res["data"]["chat_id"] == chat_assistant_ids[0]
|
||||||
|
else:
|
||||||
|
assert res["message"] == expected_message
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"chat_assistant_id, expected_code, expected_message",
|
||||||
|
[
|
||||||
|
("", 100, "<MethodNotAllowed '405: Method Not Allowed'>"),
|
||||||
|
("invalid_chat_assistant_id", 102, "You do not own the assistant."),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_invalid_chat_assistant_id(self, get_http_api_auth, chat_assistant_id, expected_code, expected_message):
|
||||||
|
res = create_session_with_chat_assistant(get_http_api_auth, chat_assistant_id, {"name": "valid_name"})
|
||||||
|
assert res["code"] == expected_code
|
||||||
|
assert res["message"] == expected_message
|
||||||
|
|
||||||
|
@pytest.mark.slow
|
||||||
|
def test_concurrent_create_session(self, get_http_api_auth, add_chat_assistants):
|
||||||
|
chunk_num = 1000
|
||||||
|
_, _, chat_assistant_ids = add_chat_assistants
|
||||||
|
res = list_session_with_chat_assistants(get_http_api_auth, chat_assistant_ids[0])
|
||||||
|
if res["code"] != 0:
|
||||||
|
assert False, res
|
||||||
|
chunks_count = len(res["data"])
|
||||||
|
|
||||||
|
with ThreadPoolExecutor(max_workers=5) as executor:
|
||||||
|
futures = [
|
||||||
|
executor.submit(
|
||||||
|
create_session_with_chat_assistant,
|
||||||
|
get_http_api_auth,
|
||||||
|
chat_assistant_ids[0],
|
||||||
|
{"name": f"session with chat assistant test {i}"},
|
||||||
|
)
|
||||||
|
for i in range(chunk_num)
|
||||||
|
]
|
||||||
|
responses = [f.result() for f in futures]
|
||||||
|
assert all(r["code"] == 0 for r in responses)
|
||||||
|
res = list_session_with_chat_assistants(get_http_api_auth, chat_assistant_ids[0], {"page_size": chunk_num})
|
||||||
|
if res["code"] != 0:
|
||||||
|
assert False, res
|
||||||
|
assert len(res["data"]) == chunks_count + chunk_num
|
||||||
|
|
||||||
|
def test_add_session_to_deleted_chat_assistant(self, get_http_api_auth, add_chat_assistants):
|
||||||
|
_, _, chat_assistant_ids = add_chat_assistants
|
||||||
|
res = delete_chat_assistants(get_http_api_auth, {"ids": [chat_assistant_ids[0]]})
|
||||||
|
assert res["code"] == 0
|
||||||
|
res = create_session_with_chat_assistant(get_http_api_auth, chat_assistant_ids[0], {"name": "valid_name"})
|
||||||
|
print(res)
|
||||||
|
assert res["code"] == 102
|
||||||
|
assert res["message"] == "You do not own the assistant."
|
Loading…
x
Reference in New Issue
Block a user