Files
wehub-resource-sync 498b235461
Build and test / Build and test AMD64 Ubuntu 22.04 (push) Failing after 0s
Publish Builder / amazonlinux2023 (push) Failing after 1s
Build and test / UT for Go (push) Has been skipped
Publish KRTE Images / KRTE (push) Failing after 1s
Build and test / Integration Test (push) Has been skipped
Build and test / Upload Code Coverage (push) Has been skipped
Publish Builder / rockylinux9 (push) Failing after 1s
Publish Builder / ubuntu22.04 (push) Failing after 0s
Publish Builder / ubuntu24.04 (push) Failing after 0s
Publish Gpu Builder / publish-gpu-builder (push) Failing after 1s
Publish Test Images / PyTest (push) Failing after 0s
Build and test / UT for Cpp (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:31:17 +08:00

277 lines
11 KiB
Python

"""
CDC sync tests for collection property operations.
"""
import time
from .base import TestCDCSyncBase, logger
class TestCDCSyncCollectionProperties(TestCDCSyncBase):
"""Test CDC sync for collection property (alter/drop) operations."""
def setup_method(self):
"""Setup for each test method."""
self.resources_to_cleanup = []
def teardown_method(self):
"""Cleanup after each test method - only cleanup upstream, downstream will sync."""
upstream_client = getattr(self, "_upstream_client", None)
if upstream_client:
for resource_type, resource_name in self.resources_to_cleanup:
if resource_type == "collection":
self.cleanup_collection(upstream_client, resource_name)
time.sleep(1) # Allow cleanup to sync to downstream
def _create_basic_collection(self, client, c_name):
"""Create a default schema collection, insert 100 rows, and create HNSW index."""
schema = self.create_default_schema(client)
client.create_collection(
collection_name=c_name,
schema=schema,
consistency_level="Strong",
)
# Insert 100 rows
test_data = self.generate_test_data(100)
client.insert(c_name, test_data)
# Create HNSW index on vector field
index_params = client.prepare_index_params()
index_params.add_index(
field_name="vector",
index_type="HNSW",
metric_type="L2",
params={"M": 8, "efConstruction": 64},
)
client.create_index(c_name, index_params)
def test_ttl_sync(self, upstream_client, downstream_client, sync_timeout):
"""Test ALTER_COLLECTION_PROPERTIES (TTL) sync."""
# Store upstream client for teardown
self._upstream_client = upstream_client
c_name = self.gen_unique_name("test_col_ttl")
self.resources_to_cleanup.append(("collection", c_name))
# Initial cleanup
self.cleanup_collection(upstream_client, c_name)
# Create collection
self._create_basic_collection(upstream_client, c_name)
# Wait for collection to sync downstream
def check_create():
return downstream_client.has_collection(c_name)
assert self.wait_for_sync(check_create, sync_timeout, f"create collection {c_name}")
# Alter collection TTL property
upstream_client.alter_collection_properties(
collection_name=c_name,
properties={"collection.ttl.seconds": "3600"},
)
# Wait for property to sync downstream
def check_ttl():
try:
desc = downstream_client.describe_collection(c_name)
props = desc.get("properties", {})
logger.info(f"Downstream collection properties: {props}")
return str(props.get("collection.ttl.seconds", "")) == "3600"
except Exception as e:
logger.warning(f"Check TTL sync failed: {e}")
return False
assert self.wait_for_sync(check_ttl, sync_timeout, f"TTL property sync for {c_name}")
def test_mmap_sync(self, upstream_client, downstream_client, sync_timeout):
"""Test ALTER_COLLECTION_PROPERTIES (mmap.enabled) sync."""
# Store upstream client for teardown
self._upstream_client = upstream_client
c_name = self.gen_unique_name("test_col_mmap")
self.resources_to_cleanup.append(("collection", c_name))
# Initial cleanup
self.cleanup_collection(upstream_client, c_name)
# Create collection
self._create_basic_collection(upstream_client, c_name)
# Wait for collection to sync downstream
def check_create():
return downstream_client.has_collection(c_name)
assert self.wait_for_sync(check_create, sync_timeout, f"create collection {c_name}")
# Alter mmap.enabled property
upstream_client.alter_collection_properties(
collection_name=c_name,
properties={"mmap.enabled": "true"},
)
# Wait for property to sync downstream
def check_mmap():
try:
desc = downstream_client.describe_collection(c_name)
props = desc.get("properties", {})
logger.info(f"Downstream collection properties: {props}")
return str(props.get("mmap.enabled", "")).lower() == "true"
except Exception as e:
logger.warning(f"Check mmap sync failed: {e}")
return False
assert self.wait_for_sync(check_mmap, sync_timeout, f"mmap property sync for {c_name}")
def test_autocompaction_sync(self, upstream_client, downstream_client, sync_timeout):
"""Test ALTER_COLLECTION_PROPERTIES (autocompaction.enabled) sync."""
# Store upstream client for teardown
self._upstream_client = upstream_client
c_name = self.gen_unique_name("test_col_autocomp")
self.resources_to_cleanup.append(("collection", c_name))
# Initial cleanup
self.cleanup_collection(upstream_client, c_name)
# Create collection
self._create_basic_collection(upstream_client, c_name)
# Wait for collection to sync downstream
def check_create():
return downstream_client.has_collection(c_name)
assert self.wait_for_sync(check_create, sync_timeout, f"create collection {c_name}")
# Alter autocompaction property
upstream_client.alter_collection_properties(
collection_name=c_name,
properties={"collection.autocompaction.enabled": "true"},
)
# Wait for property to sync downstream
def check_autocomp():
try:
desc = downstream_client.describe_collection(c_name)
props = desc.get("properties", {})
logger.info(f"Downstream collection properties: {props}")
return str(props.get("collection.autocompaction.enabled", "")).lower() == "true"
except Exception as e:
logger.warning(f"Check autocompaction sync failed: {e}")
return False
assert self.wait_for_sync(check_autocomp, sync_timeout, f"autocompaction property sync for {c_name}")
def test_alter_multiple_properties(self, upstream_client, downstream_client, sync_timeout):
"""Test ALTER_COLLECTION_PROPERTIES with multiple properties at once sync."""
# Store upstream client for teardown
self._upstream_client = upstream_client
c_name = self.gen_unique_name("test_col_multi_props")
self.resources_to_cleanup.append(("collection", c_name))
# Initial cleanup
self.cleanup_collection(upstream_client, c_name)
# Create collection
self._create_basic_collection(upstream_client, c_name)
# Wait for collection to sync downstream
def check_create():
return downstream_client.has_collection(c_name)
assert self.wait_for_sync(check_create, sync_timeout, f"create collection {c_name}")
# Alter all 3 properties at once
upstream_client.alter_collection_properties(
collection_name=c_name,
properties={
"collection.ttl.seconds": "3600",
"mmap.enabled": "true",
"collection.autocompaction.enabled": "true",
},
)
# Wait for all 3 properties to sync downstream
def check_all_props():
try:
desc = downstream_client.describe_collection(c_name)
props = desc.get("properties", {})
logger.info(f"Downstream collection properties: {props}")
ttl_ok = str(props.get("collection.ttl.seconds", "")) == "3600"
mmap_ok = str(props.get("mmap.enabled", "")).lower() == "true"
autocomp_ok = str(props.get("collection.autocompaction.enabled", "")).lower() == "true"
return ttl_ok and mmap_ok and autocomp_ok
except Exception as e:
logger.warning(f"Check all properties sync failed: {e}")
return False
assert self.wait_for_sync(check_all_props, sync_timeout, f"all properties sync for {c_name}")
def test_drop_properties_sync(self, upstream_client, downstream_client, sync_timeout):
"""Test DROP_COLLECTION_PROPERTIES — set TTL + mmap, drop TTL, verify TTL gone and mmap remains."""
# Store upstream client for teardown
self._upstream_client = upstream_client
c_name = self.gen_unique_name("test_col_drop_props")
self.resources_to_cleanup.append(("collection", c_name))
# Initial cleanup
self.cleanup_collection(upstream_client, c_name)
# Create collection
self._create_basic_collection(upstream_client, c_name)
# Wait for collection to sync downstream
def check_create():
return downstream_client.has_collection(c_name)
assert self.wait_for_sync(check_create, sync_timeout, f"create collection {c_name}")
# Set TTL and mmap properties
upstream_client.alter_collection_properties(
collection_name=c_name,
properties={
"collection.ttl.seconds": "3600",
"mmap.enabled": "true",
},
)
# Wait for both properties to sync downstream
def check_props_set():
try:
desc = downstream_client.describe_collection(c_name)
props = desc.get("properties", {})
ttl_set = str(props.get("collection.ttl.seconds", "")) == "3600"
mmap_set = str(props.get("mmap.enabled", "")).lower() == "true"
return ttl_set and mmap_set
except Exception as e:
logger.warning(f"Check properties set failed: {e}")
return False
assert self.wait_for_sync(check_props_set, sync_timeout, f"set properties for {c_name}")
# Drop TTL property
upstream_client.drop_collection_properties(
collection_name=c_name,
property_keys=["collection.ttl.seconds"],
)
# Wait for TTL to be gone but mmap to remain on downstream
def check_drop_ttl():
try:
desc = downstream_client.describe_collection(c_name)
props = desc.get("properties", {})
logger.info(f"Downstream collection properties after drop: {props}")
ttl_gone = "collection.ttl.seconds" not in props
mmap_remains = str(props.get("mmap.enabled", "")).lower() == "true"
return ttl_gone and mmap_remains
except Exception as e:
logger.warning(f"Check drop TTL sync failed: {e}")
return False
assert self.wait_for_sync(check_drop_ttl, sync_timeout, f"drop TTL property sync for {c_name}")