From 24cb4ac0fcc6bfa88432c5c6a1b061f601458baf Mon Sep 17 00:00:00 2001 From: phanirithvij Date: Wed, 25 Mar 2026 18:30:32 +0530 Subject: [PATCH 1/5] linux only metrics Signed-off-by: phanirithvij --- tests/metrics_test.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/tests/metrics_test.py b/tests/metrics_test.py index 12fc300..6f2295d 100644 --- a/tests/metrics_test.py +++ b/tests/metrics_test.py @@ -42,18 +42,22 @@ def test_init_async(fake_async_api_call: AsyncApiCall) -> None: ) assert metrics.resource_path == "/metrics.json" # noqa: WPS437 +import platform + def test_actual_retrieve(actual_metrics: Metrics) -> None: """Test that the Metrics object can retrieve metrics on Typesense server and verify response structure.""" response = actual_metrics.retrieve() - assert "system_cpu_active_percentage" in response + if platform.system() == "Linux": + assert "system_cpu_active_percentage" in response + assert "system_network_received_bytes" in response + assert "system_network_sent_bytes" in response + assert "system_disk_total_bytes" in response assert "system_disk_used_bytes" in response assert "system_memory_total_bytes" in response assert "system_memory_used_bytes" in response - assert "system_network_received_bytes" in response - assert "system_network_sent_bytes" in response assert "typesense_memory_active_bytes" in response assert "typesense_memory_allocated_bytes" in response assert "typesense_memory_fragmentation_ratio" in response @@ -68,13 +72,15 @@ async def test_actual_retrieve_async(actual_async_metrics: AsyncMetrics) -> None """Test that the AsyncMetrics object can retrieve metrics on Typesense server and verify response structure.""" response = await actual_async_metrics.retrieve() - assert "system_cpu_active_percentage" in response + if platform.system() == "Linux": + assert "system_cpu_active_percentage" in response + assert "system_network_received_bytes" in response + assert "system_network_sent_bytes" in response + assert "system_disk_total_bytes" in response assert "system_disk_used_bytes" in response assert "system_memory_total_bytes" in response assert "system_memory_used_bytes" in response - assert "system_network_received_bytes" in response - assert "system_network_sent_bytes" in response assert "typesense_memory_active_bytes" in response assert "typesense_memory_allocated_bytes" in response assert "typesense_memory_fragmentation_ratio" in response From ed2f6f31f74fae21cb00b6ea3da92b300fadce76 Mon Sep 17 00:00:00 2001 From: phanirithvij Date: Wed, 25 Mar 2026 19:05:02 +0530 Subject: [PATCH 2/5] generated temp path Signed-off-by: phanirithvij --- tests/operations_test.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/operations_test.py b/tests/operations_test.py index b48b946..71c134e 100644 --- a/tests/operations_test.py +++ b/tests/operations_test.py @@ -69,11 +69,11 @@ def test_cache_clear(actual_operations: Operations) -> None: assert response["success"] -def test_snapshot(actual_operations: Operations) -> None: +def test_snapshot(actual_operations: Operations, tmp_path) -> None: """Test that the Operations object can perform the snapshot operation.""" response = actual_operations.perform( "snapshot", - {"snapshot_path": "/tmp"}, # noqa: S108 + {"snapshot_path": str(tmp_path)}, # noqa: S108 ) assert response["success"] From 90047673e4191ffaa6431059f9a8c1ffb31ea3cb Mon Sep 17 00:00:00 2001 From: phanirithvij Date: Wed, 25 Mar 2026 19:02:46 +0530 Subject: [PATCH 3/5] tests fix endpoint path _endpoint_path is not a function anymore Signed-off-by: phanirithvij --- tests/override_test.py | 4 ++-- tests/overrides_test.py | 4 ++-- tests/synonym_test.py | 4 ++-- tests/synonyms_test.py | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/override_test.py b/tests/override_test.py index 89526c7..47fc81b 100644 --- a/tests/override_test.py +++ b/tests/override_test.py @@ -47,7 +47,7 @@ def test_init(fake_api_call: ApiCall) -> None: fake_api_call.config.nearest_node, ) assert ( - override._endpoint_path() # noqa: WPS437 + override._endpoint_path # noqa: WPS437 == "/collections/companies/overrides/company_override" ) @@ -104,7 +104,7 @@ def test_init_async(fake_async_api_call: AsyncApiCall) -> None: fake_async_api_call.config.nearest_node, ) assert ( - override._endpoint_path() # noqa: WPS437 + override._endpoint_path # noqa: WPS437 == "/collections/companies/overrides/company_override" ) diff --git a/tests/overrides_test.py b/tests/overrides_test.py index a9376b5..de4de73 100644 --- a/tests/overrides_test.py +++ b/tests/overrides_test.py @@ -61,7 +61,7 @@ def test_get_missing_override(fake_overrides: Overrides) -> None: ) assert override.collection_name == "companies" assert ( - override._endpoint_path() # noqa: WPS437 + override._endpoint_path # noqa: WPS437 == "/collections/companies/overrides/company_override" ) @@ -186,7 +186,7 @@ def test_get_missing_override_async(fake_async_overrides) -> None: ) assert override.collection_name == "companies" assert ( - override._endpoint_path() # noqa: WPS437 + override._endpoint_path # noqa: WPS437 == "/collections/companies/overrides/company_override" ) diff --git a/tests/synonym_test.py b/tests/synonym_test.py index cfe6e51..d9affd9 100644 --- a/tests/synonym_test.py +++ b/tests/synonym_test.py @@ -45,7 +45,7 @@ def test_init(fake_api_call: ApiCall) -> None: fake_api_call.config.nearest_node, ) assert ( - synonym._endpoint_path() # noqa: WPS437 + synonym._endpoint_path # noqa: WPS437 == "/collections/companies/synonyms/company_synonym" ) @@ -99,7 +99,7 @@ def test_init_async(fake_async_api_call: AsyncApiCall) -> None: fake_async_api_call.config.nearest_node, ) assert ( - synonym._endpoint_path() # noqa: WPS437 + synonym._endpoint_path # noqa: WPS437 == "/collections/companies/synonyms/company_synonym" ) diff --git a/tests/synonyms_test.py b/tests/synonyms_test.py index 3402493..afe8638 100644 --- a/tests/synonyms_test.py +++ b/tests/synonyms_test.py @@ -62,7 +62,7 @@ def test_get_missing_synonym(fake_synonyms: Synonyms) -> None: ) assert synonym.collection_name == "companies" assert ( - synonym._endpoint_path() # noqa: WPS437 + synonym._endpoint_path # noqa: WPS437 == "/collections/companies/synonyms/company_synonym" ) @@ -174,7 +174,7 @@ def test_get_missing_synonym_async(fake_async_synonyms) -> None: ) assert synonym.collection_name == "companies" assert ( - synonym._endpoint_path() # noqa: WPS437 + synonym._endpoint_path # noqa: WPS437 == "/collections/companies/synonyms/company_synonym" ) From f6989c8e29fcb03bf76f1b143d116f081091fad1 Mon Sep 17 00:00:00 2001 From: phanirithvij Date: Wed, 25 Mar 2026 19:35:38 +0530 Subject: [PATCH 4/5] tests fix rule_id rule_id is not found for this class but rule_name exists with the expected value Signed-off-by: phanirithvij --- tests/analytics_rules_v1_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/analytics_rules_v1_test.py b/tests/analytics_rules_v1_test.py index d222d99..d1021d8 100644 --- a/tests/analytics_rules_v1_test.py +++ b/tests/analytics_rules_v1_test.py @@ -45,7 +45,7 @@ def test_get_missing_analytics_rule(fake_analytics_rules: AnalyticsRulesV1) -> N """Test that the AnalyticsRulesV1 object can get a missing analytics_rule.""" analytics_rule = fake_analytics_rules["company_analytics_rule"] - assert analytics_rule.rule_id == "company_analytics_rule" + assert analytics_rule.rule_name == "company_analytics_rule" assert_match_object(analytics_rule.api_call, fake_analytics_rules.api_call) assert_object_lists_match( analytics_rule.api_call.node_manager.nodes, From 6eecb90897548584b8907731abf981237e032997 Mon Sep 17 00:00:00 2001 From: Fanis Tharropoulos Date: Thu, 7 May 2026 18:59:56 +0300 Subject: [PATCH 5/5] test: gate v30 collection schema expectations - keep v29.0 and earlier tests passing --- tests/collection_test.py | 31 +++-- tests/collections_test.py | 242 +++++++++++++------------------------- 2 files changed, 106 insertions(+), 167 deletions(-) diff --git a/tests/collection_test.py b/tests/collection_test.py index 7eb29fa..30093d1 100644 --- a/tests/collection_test.py +++ b/tests/collection_test.py @@ -5,12 +5,24 @@ assert_object_lists_match, assert_to_contain_object, ) +from tests.utils.version import is_v30_or_above from typesense.sync.api_call import ApiCall +from typesense.sync.client import Client from typesense.sync.collection import Collection from typesense.sync.collections import Collections from typesense.types.collection import CollectionSchema +is_v30_or_above_server = is_v30_or_above( + Client( + { + "api_key": "xyz", + "nodes": [{"host": "localhost", "port": 8108, "protocol": "http"}], + } + ) +) + + def test_init(fake_api_call: ApiCall) -> None: """Test that the Collection object is initialized correctly.""" collection = Collection(fake_api_call, "companies") @@ -52,7 +64,6 @@ def test_actual_retrieve( "infix": False, "stem": False, "stem_dictionary": "", - "truncate_len": 100, "store": True, }, { @@ -66,7 +77,6 @@ def test_actual_retrieve( "infix": False, "stem": False, "stem_dictionary": "", - "truncate_len": 100, "store": True, }, ], @@ -74,9 +84,12 @@ def test_actual_retrieve( "num_documents": 0, "symbols_to_index": [], "token_separators": [], - "synonym_sets": [], - "curation_sets": [], } + if is_v30_or_above_server: + expected["synonym_sets"] = [] + expected["curation_sets"] = [] + expected["fields"][0]["truncate_len"] = 100 + expected["fields"][1]["truncate_len"] = 100 response.pop("created_at") @@ -93,10 +106,8 @@ def test_actual_update( {"fields": [{"name": "num_locations", "type": "int32"}]}, ) - expected: CollectionSchema = { - "fields": [ - {"name": "num_locations", "truncate_len": 100, "type": "int32"}, - ], - } + expected_field = {"name": "num_locations", "type": "int32"} + if is_v30_or_above_server: + expected_field["truncate_len"] = 100 - assert_to_contain_object(response.get("fields")[0], expected.get("fields")[0]) + assert_to_contain_object(response.get("fields")[0], expected_field) diff --git a/tests/collections_test.py b/tests/collections_test.py index 788e3dc..94e3c60 100644 --- a/tests/collections_test.py +++ b/tests/collections_test.py @@ -1,6 +1,5 @@ """Tests for the Collections class.""" - import sys from typesense.async_.api_call import AsyncApiCall @@ -13,11 +12,68 @@ from tests.utils.object_assertions import assert_match_object, assert_object_lists_match from typesense.sync.api_call import ApiCall +from tests.utils.version import is_v30_or_above from typesense.sync.collections import Collections from typesense.async_.collections import AsyncCollections +from typesense.sync.client import Client from typesense.types.collection import CollectionSchema +IS_V30_OR_ABOVE = is_v30_or_above( + Client( + { + "api_key": "xyz", + "nodes": [{"host": "localhost", "port": 8108, "protocol": "http"}], + } + ) +) + + +def expected_collection_field( + name: str, + type_: str, + *, + sort: bool, +) -> dict[str, typing.Any]: + field: dict[str, typing.Any] = { + "name": name, + "type": type_, + "facet": False, + "index": True, + "optional": False, + "locale": "", + "sort": sort, + "infix": False, + "stem": False, + "stem_dictionary": "", + "store": True, + } + if IS_V30_OR_ABOVE: + field["truncate_len"] = 100 + return field + + +def expected_collection_schema( + *, + default_sorting_field: str, + fields: typing.List[dict[str, typing.Any]], + name: str, +) -> CollectionSchema: + expected: CollectionSchema = { + "default_sorting_field": default_sorting_field, + "enable_nested_fields": False, + "fields": fields, + "name": name, + "num_documents": 0, + "symbols_to_index": [], + "token_separators": [], + } + if IS_V30_OR_ABOVE: + expected["synonym_sets"] = [] + expected["curation_sets"] = [] + return expected + + def test_init(fake_api_call: ApiCall) -> None: """Test that the Collections object is initialized correctly.""" collections = Collections(fake_api_call) @@ -98,46 +154,14 @@ def test_get_existing_collection(fake_collections: Collections) -> None: def test_actual_create(actual_collections: Collections, delete_all: None) -> None: """Test that the Collections object can create a collection on Typesense Server.""" - expected: CollectionSchema = { - "default_sorting_field": "", - "enable_nested_fields": False, - "fields": [ - { - "name": "company_name", - "type": "string", - "facet": False, - "index": True, - "optional": False, - "locale": "", - "sort": False, - "infix": False, - "stem": False, - "stem_dictionary": "", - "truncate_len": 100, - "store": True, - }, - { - "name": "num_employees", - "type": "int32", - "facet": False, - "index": True, - "optional": False, - "locale": "", - "sort": False, - "infix": False, - "stem": False, - "stem_dictionary": "", - "truncate_len": 100, - "store": True, - }, + expected = expected_collection_schema( + default_sorting_field="", + fields=[ + expected_collection_field("company_name", "string", sort=False), + expected_collection_field("num_employees", "int32", sort=False), ], - "name": "companies", - "num_documents": 0, - "symbols_to_index": [], - "token_separators": [], - "synonym_sets": [], - "curation_sets": [], - } + name="companies", + ) response = actual_collections.create( { @@ -170,46 +194,14 @@ def test_actual_retrieve( response = actual_collections.retrieve() expected: typing.List[CollectionSchema] = [ - { - "default_sorting_field": "num_employees", - "enable_nested_fields": False, - "fields": [ - { - "name": "company_name", - "type": "string", - "facet": False, - "index": True, - "optional": False, - "locale": "", - "sort": False, - "infix": False, - "stem": False, - "stem_dictionary": "", - "truncate_len": 100, - "store": True, - }, - { - "name": "num_employees", - "type": "int32", - "facet": False, - "index": True, - "optional": False, - "locale": "", - "sort": True, - "infix": False, - "stem": False, - "stem_dictionary": "", - "truncate_len": 100, - "store": True, - }, + expected_collection_schema( + default_sorting_field="num_employees", + fields=[ + expected_collection_field("company_name", "string", sort=False), + expected_collection_field("num_employees", "int32", sort=True), ], - "name": "companies", - "num_documents": 0, - "symbols_to_index": [], - "token_separators": [], - "synonym_sets": [], - "curation_sets": [], - }, + name="companies", + ), ] response[0].pop("created_at") @@ -235,46 +227,14 @@ async def test_actual_create_async( actual_async_collections: AsyncCollections, delete_all: None ) -> None: """Test that the Collections object can create a collection on Typesense Server.""" - expected: CollectionSchema = { - "default_sorting_field": "", - "enable_nested_fields": False, - "fields": [ - { - "name": "company_name", - "type": "string", - "facet": False, - "index": True, - "optional": False, - "locale": "", - "sort": False, - "infix": False, - "stem": False, - "stem_dictionary": "", - "truncate_len": 100, - "store": True, - }, - { - "name": "num_employees", - "type": "int32", - "facet": False, - "index": True, - "optional": False, - "locale": "", - "sort": False, - "infix": False, - "stem": False, - "stem_dictionary": "", - "truncate_len": 100, - "store": True, - }, + expected = expected_collection_schema( + default_sorting_field="", + fields=[ + expected_collection_field("company_name", "string", sort=False), + expected_collection_field("num_employees", "int32", sort=False), ], - "name": "companies", - "num_documents": 0, - "symbols_to_index": [], - "token_separators": [], - "synonym_sets": [], - "curation_sets": [], - } + name="companies", + ) response = await actual_async_collections.create( { @@ -307,46 +267,14 @@ async def test_actual_retrieve_async( response = await actual_async_collections.retrieve() expected: typing.List[CollectionSchema] = [ - { - "default_sorting_field": "num_employees", - "enable_nested_fields": False, - "fields": [ - { - "name": "company_name", - "type": "string", - "facet": False, - "index": True, - "optional": False, - "locale": "", - "sort": False, - "infix": False, - "stem": False, - "stem_dictionary": "", - "truncate_len": 100, - "store": True, - }, - { - "name": "num_employees", - "type": "int32", - "facet": False, - "index": True, - "optional": False, - "locale": "", - "sort": True, - "infix": False, - "stem": False, - "stem_dictionary": "", - "truncate_len": 100, - "store": True, - }, + expected_collection_schema( + default_sorting_field="num_employees", + fields=[ + expected_collection_field("company_name", "string", sort=False), + expected_collection_field("num_employees", "int32", sort=True), ], - "name": "companies", - "num_documents": 0, - "symbols_to_index": [], - "token_separators": [], - "synonym_sets": [], - "curation_sets": [], - }, + name="companies", + ), ] response[0].pop("created_at")