## Summary
- GPU→L1, zip() for positional index, add metric_type, fix spelling
- IVF_SQ8→DISKANN, skip DISKANN mmap, fix INT8 metric, filter assertions
- Fix false-pass bypass in check_search_results for empty hits
## Code Review Fix (0e4ad86c13)
### check_search_results: remove empty-hits bypass
`check_search_results` in `func_check.py` had a `if len(hits) == 0:
continue` guard that silently skipped all verification (including limit
check) when search returned no results. This caused tests with filters
matching zero rows to false-pass instead of failing.
Removed the 2-line guard entirely. The existing `assert len(hits) ==
check_items["limit"]` already handles this correctly — when limit is
specified and hits is empty, the assertion properly fails.
**Impact:** `test_search_with_scalar_field` in
`test_milvus_client_search_diskann.py` filters `int64 in [1, 2, 3, 4]`
on randomly-generated INT64 data (non-PK field uses full-range random
values). This matches 0 rows, and previously false-passed due to the
bypass. After the fix, it correctly fails. The filter in the test should
also be updated to use values that exist in the data.
Verified: ran all 6 PR test files (L0+L1, `-n 4`) — 88 passed, 1
expected failure (`test_search_with_scalar_field`), 9 skipped.
issue: #48048🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Signed-off-by: yanliang567 <82361606+yanliang567@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
## Summary
- Add `TestMilvusClientRbacPrefixIsolation` class to
`test_milvus_client_rbac.py`
- Validates RBAC metadata integrity and permission isolation when
usernames/roles have prefix relationships (e.g. `user1` vs `user11`),
covering issue #47998 and PR #48053
- Single test method with setup/teardown per run, using random prefix
for test data isolation
## Related Issues
issue: #47998
pr: #48053
## Test Report
https://zilliverse.feishu.cn/docx/HaFld6sCyoMz19xOsC3cPCqdncg
## Test plan
- [x] Verified on v2.6.9 (pre-fix): FAIL on #03 DescribeUser
(empty-string role) and #23 ListDatabases
- [x] Verified on master-20260319 (post-fix): all PASS
- [x] Teardown cleans up all test data using `force_drop`, no residual
data
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Signed-off-by: lyyyuna <yiyang.li@zilliz.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
/kind improvement
add testcases and fix a related issue
issue: #47928
---------
Signed-off-by: zhuwenxing <wenxing.zhu@zilliz.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Summary
- Add `test_upsert_overwrite_null_ttl_with_short_ttl` verifying that
upserting NULL TTL with a short TTL correctly expires data across
growing/sealed segments, release/reload, and compaction
- Remove skipped `test_alter_remove_entity_ttl_field` test (blocked by
#47416)
- Fix flaky TTL test cases by adding search retry logic — search and
query take different code paths and TTL filtering propagates at
different speeds, so search assertions need their own polling/retry
issue: #47482, #48260
Signed-off-by: FeilongHou <feilong.hou@zilliz.com>
## Test plan
- [x] New test case passes against a Milvus instance with entity TTL
support
- [x] CI passes
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Signed-off-by: Eric Hou <eric.hou@zilliz.com>
Co-authored-by: Eric Hou <eric.hou@zilliz.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
## What does this PR do?
Fix a flaky test in `test_milvus_client_hybrid_search_v2.py`.
## Why?
`test_hybrid_search_as_search` asserts that hybrid search (single field
+ WeightedRanker) returns the same ordered result list as a regular
search. When two results have tied scores, tie-breaking order is
non-deterministic across architectures and runs due to floating-point
differences — this causes spurious failures on ARM e2e CI.
Comparing ID sets instead of ordered lists preserves the intent of the
test (same result candidates returned) while being robust to ordering of
ties.
---------
Signed-off-by: xiaofanluan <xiaofan.luan@zilliz.com>
## Summary
- Fix partial update failing when dynamic field is enabled but no
dynamic data is provided during upsert
- Fix partial update failing when field has default value but is not
nullable
- Add E2E test cases covering dynamic field and default value scenarios
for partial update
issue: https://github.com/milvus-io/milvus/issues/47957,
https://github.com/milvus-io/milvus/issues/48002
## Test plan
- [x] Added E2E tests for partial update with dynamic fields
- [x] Added E2E tests for partial update with default value fields
- [x] Verified upsert works with empty dynamic field data
- [x] Verified upsert works with non-nullable fields that have default
values
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Signed-off-by: Eric Hou <eric.hou@zilliz.com>
Co-authored-by: Eric Hou <eric.hou@zilliz.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Summary
- Remove `metric_type` from `DEFAULT_SEARCH_PARAM` and
`DEFAULT_INT8_SEARCH_PARAM` in chaos test constants, letting the server
auto-infer metric type from the index
- Fixes chaos test failures (broken since build #24014) where
`AddVectorFieldChecker` creates COSINE-indexed vector fields but all
search checkers hardcode `metric_type: L2`
## Root Cause
In chaos tests, `AddVectorFieldChecker` dynamically adds nullable
FLOAT_VECTOR fields with **COSINE** HNSW index. After etcd pod-failure
recovery, `SearchChecker`, `HybridSearchChecker`, and
`NullVectorSearchChecker` re-initialize and discover these new fields.
When they search on them using hardcoded `metric_type: L2`, the server
returns:
- `metric type not match: invalid parameter[expected=COSINE][actual=L2]`
- `hybrid_search` 0% success rate (iterates ALL vector fields)
- `search`/`null_vector_search` ~28% success rate
Reference failure: [chaos-test-cron
#24056](https://qa-jenkins.milvus.io/blue/organizations/jenkins/chaos-test-cron/detail/chaos-test-cron/24056/pipeline/)
## Test plan
- [x] Verified on Milvus master (`master-20260313-f163e94`): search
without `metric_type` correctly auto-detects L2 and COSINE from index
- [x] Verified hybrid search across mixed metric types (L2 + COSINE)
works without specifying `metric_type`
- [x] Backwards compatible: explicit `metric_type` in search params
still works
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Signed-off-by: yanliang567 <82361606+yanliang567@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Summary
- Migrate 15 partition key test cases from
`testcases/test_partition_key.py` (v1 ORM style) to
`milvus_client/test_milvus_client_partition_key.py` (v2 MilvusClient
style)
- Migrate 4 partition key isolation test cases from
`testcases/test_partition_key_isolation.py` to
`milvus_client/test_milvus_client_partition_key_isolation.py`
- Optimize isolation test parameters to prevent CI timeout: data_size
10000→1000, dim 768→128, HNSW M=30→16, efConstruction=360→64
- Remove migrated v1 test files
## Related Issues
#48048
## Test plan
- [x] All 19 migrated test cases (46 parametrized combinations) pass on
cluster (19531)
- [x] Partition key isolation tests (4 cases) all pass (~68s total, down
from >360s CI timeout)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Signed-off-by: lyyyuna <yiyang.li@zilliz.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Summary
- Set `consistency_level="Strong"` at collection creation time in chaos
`checker.py` (9 places) to ensure data correctness during chaos testing
- Add explicit `consistency_level="Strong"` to all search/query calls in
`test_all_collections_after_chaos.py` (8 places) since it operates on
pre-existing collections
## Test plan
- [x] Pod logs confirm `[consistency_level=Strong]` at CreateCollection
- [x] `describe_collection` returns `consistency_level: 0` (Strong)
- [x] Insert-then-query returns all data immediately without explicit
consistency_level param
Signed-off-by: zhuwenxing <wenxing.zhu@zilliz.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Summary
- Migrate 50+ partition test cases from `testcases/test_partition.py`
(v1 ORM style) to `milvus_client/test_milvus_client_partition.py` (v2
MilvusClient style)
- Add `gen_default_rows_data_for_upsert` helper in `common_func.py` for
row-based upsert data generation
- Enhance existing v2 tests with partition name validation and `None`
partition name coverage
- Remove migrated test cases from v1 file, keeping only v2-incompatible
cases (description params, dataframe insert)
## Related Issues
#48048
## Test plan
- [x] v1 remaining tests pass on standalone (19530) and cluster (19531)
- [x] v2 full test suite passes on standalone (148 passed, 3 failed -
replica tests need cluster)
- [x] v2 full test suite passes on cluster (151 passed, 0 failed)
- [x] v2 tests pass with 8-worker concurrency (`-n 8`) on both
environments
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Signed-off-by: lyyyuna <yiyang.li@zilliz.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Summary
Fix two bugs in chaos test checkers that cause
`test_concurrent_operation.py` to fail consistently (broken since build
#24014 in chaos-test-cron):
- **Op.hybrid_search 0% success rate**:
`HybridSearchChecker.gen_hybrid_search_request()` used a single cached
`self.dim` for all vector fields. When `AddVectorFieldChecker` adds
fields with different dimensions to the same collection, hybrid search
sends vectors with wrong dimensions, causing `vector dimension mismatch`
errors.
- **Op.add_vector_field 0% success rate**: Hardcoded `dim=32` created
dimension inconsistency with the collection schema (default `dim=128`).
The pre-check via `describe_collection` field counting was unreliable —
replaced with server-side error handling that catches `maximum vector
field` error and gracefully falls back to insert-only.
### Changes
**`tests/python_client/chaos/checker.py`:**
- `HybridSearchChecker.gen_hybrid_search_request()`: Query each vector
field's actual dimension from schema via `get_schema()` instead of using
a single cached dim
- `AddVectorFieldChecker.add_vector_field()`: Use `self.dim` instead of
hardcoded `dim=32`; catch server-side "maximum vector field" error and
fallback to insert
### Jenkins failure reference
https://qa-jenkins.milvus.io/blue/organizations/jenkins/chaos-test-cron/detail/chaos-test-cron/24056/pipeline🤖 Generated with [Claude Code](https://claude.com/claude-code)
Signed-off-by: yanliang567 <82361606+yanliang567@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Summary
Fixes#47316
- **GroupingSet::outputRowCount()**: Add null check for `lookup_` to
prevent SIGSEGV when filter matches zero rows and no input data arrives
- **ExecPlanNodeVisitor::setupRetrieveResult()**: When query result is
nullptr, build empty field_data arrays with correct schema (0 rows, N
columns) so downstream receives proper column structure instead of
missing columns
- Enable previously skipped E2E test `test_empty_result_aggregation`
## Test plan
- [x] E2E test `test_empty_result_aggregation` passes (GROUP BY +
aggregation with filter matching 0 rows returns empty result `[]`)
- [ ] Existing aggregation E2E tests still pass
- [ ] CI green
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Summary
- Add chaos test for upsert-during-node-kill: verifies TTL extension via
upsert persists after querynode kill and WAL replay
- Add chaos test for insert-during-node-kill: verifies new data with TTL
inserted during chaos is correctly handled after recovery
- Fix `_verify_correctness` to distinguish "service never recovered"
from "wrong counts"
- Strengthen `_verify_search_consistency` to require non-zero valid
results from non-expired groups
## Test plan
- [x] All 5 chaos tests pass against a Milvus cluster with Chaos Mesh
- [x] Upsert test confirms TTL extension survives querynode kill
- [x] Insert test confirms both long-TTL (alive) and short-TTL (expired)
data inserted during chaos are correctly handled after recovery
issue: https://github.com/milvus-io/milvus/issues/47482🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Signed-off-by: Eric Hou <eric.hou@zilliz.com>
Co-authored-by: Eric Hou <eric.hou@zilliz.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
issue: #47902
Integrate milvus-common commit 7b54b6e which adds
CacheWarmupPolicy_Async and a prefetch thread pool for background cache
warmup. This enables segments to be marked as loaded immediately while
cache warming happens asynchronously, reducing load latency.
---------
Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
## Summary
- Add comprehensive E2E test cases for the Entity TTL feature (#47482)
- Cover collection creation/alter with `ttl_field`, insert with
future/expired/null TTL values, upsert to extend/shorten TTL, delete
before expiry, release/reload behavior, and query/search filtering of
expired data
- Add invalid parameter test cases: non-timestamptz field, nonexistent
field, nullable=false, and conflict with collection-level TTL
- Fix existing `test_milvus_client_ttl_edge` to properly assert error on
out-of-range TTL
## Test plan
- [x] All new test cases pass against a Milvus instance with entity TTL
support enabled
- [x] Existing TTL test cases remain passing
issue: #47482
---------
Signed-off-by: Eric Hou <eric.hou@zilliz.com>
Co-authored-by: Eric Hou <eric.hou@zilliz.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Summary
Wire three null-vector checkers into the chaos test concurrent operation
pipeline (`test_concurrent_operation.py`):
- **NullVectorSearchChecker** — detects NaN distances from null vector
leaks in search index
- **NullVectorQueryChecker** — validates null/non-null ratio consistency
in queries
- **AddVectorFieldChecker** — dynamically adds nullable FLOAT_VECTOR
fields, creates index, inserts data, and verifies
These checkers are already implemented in `checker.py` but were not
registered in `init_health_checkers()`. The default collection schema
already has nullable vector fields (`float_vector` and `image_emb` both
`nullable=True`), so the checkers use the shared collection name.
issue: #47867
### Changes
**Modified:**
- `tests/python_client/chaos/testcases/test_concurrent_operation.py`:
Added imports and registered 3 checkers
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Signed-off-by: yanliang567 <82361606+yanliang567@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Summary
- **balancer_test**: use `defer b.Close()` immediately after creation in
`TestBalancer_WithRecoveryLag` to prevent goroutine leak causing DATA
RACE with next test's `resource.InitForTest()`
- **impl_test**: initialize `globalMetaCache` mock in
`TestProxyDropDatabase` to avoid nil pointer from stale global state
- **client_test**: replace `log.Fatalf` with `t.Fatalf` for listen
errors, silence `s.Serve()` return on `s.Stop()`, fix `lis.Addr()`
called before error check
- **test_milvus_client_ttl**: increase TTL from 5s to 20s with 2s margin
zones around TTL boundaries to ensure all assertion phases have
meaningful windows
## Test plan
- [ ] CI ut-go passes (covers fixes 1-3)
- [ ] CI e2e passes (covers fix 4)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Signed-off-by: Li Liu <li.liu@zilliz.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Related to #46199
## Summary
- Remove unused Python test dependencies: `ndg-httpsclient`,
`pyopenssl`, `pyasn1`, `pytest-parallel`, `timeout-decorator`
- Restore `pytest-assume==2.4.3` and `Unidecode==1.3.8` (actively used
in test code)
- Clean up dead `timeout_decorator` import and commented-out code in
`collection_wrapper.py`
## Performance impact
No production performance impact. All changes are in
`tests/python_client/` — test dependencies and test utility code only.
Milvus has no Python in its runtime (Go + C++ only).
| Change | Scope | Impact |
|--------|-------|--------|
| Remove 5 unused pip packages | Test `requirements.txt` | Faster test
env setup (~5 fewer packages to install) |
| Remove dead `timeout_decorator` import + commented-out code |
`collection_wrapper.py` | Cleaner test code, no behavior change |
## Test plan
- [ ] CI E2E tests pass (Python test suite runs successfully with
updated dependencies)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Signed-off-by: Li Liu <li.liu@zilliz.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Summary
- Increase the default `maxVectorFieldNum` from **4** to **10** to
accommodate the growing variety of vector types (dense, sparse,
function-based) supported by Milvus
- Update related test constants and hardcoded values in both Go and
Python test suites
## Changes
- `configs/milvus.yaml`: default config value 4 → 10
- `pkg/util/paramtable/component_param.go`: Go param default "4" → "10"
- `tests/go_client/common/consts.go`: Go test constant 4 → 10
- `tests/python_client/common/common_type.py`: Python test constant 4 →
10
- `tests/python_client/milvus_client/test_milvus_client_collection.py`:
replace hardcoded "4" in error message with constant reference
Closes#47402
## Test plan
- [x] Verify collection creation with up to 10 vector fields succeeds
- [x] Verify collection creation with 11+ vector fields fails with
proper error message
- [x] Run existing Go integration tests (`tests/go_client`)
- [x] Run existing Python client tests (`tests/python_client`)
Signed-off-by: zhuwenxing <wenxing.zhu@zilliz.com>
## Summary
Add 4 test cases to `TestQueryAggregationSharedV2` covering GROUP BY on
nullable fields, verifying the fix for #47350 (PR #47445).
**Related issue**: #47350
### Changes
**Schema additions** to the shared collection:
- `c10_nullable_varchar`: VARCHAR (nullable, 7 unique values + ~15%
NULL)
- `c11_nullable_int16`: INT16 (nullable, 5 unique values + ~15% NULL)
**New tests:**
| Test | What it verifies |
|------|-----------------|
| `test_group_by_nullable_varchar_field` | GROUP BY nullable VARCHAR
returns actual values (not all NULL) + aggregation correctness |
| `test_group_by_nullable_int16_field` | GROUP BY nullable INT16 returns
actual values + aggregation correctness |
| `test_multi_column_group_by_with_nullable_field` | Multi-column GROUP
BY with one nullable column |
| `test_search_group_by_nullable_field` | Search with GROUP BY on
nullable field returns actual group values |
### Test Plan
- [x] All 4 new tests passed against Milvus 2.6.6
- [x] All 28 existing tests still pass (0 regressions)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Signed-off-by: yanliang567 <82361606+yanliang567@users.noreply.github.com>
## Summary
- Split snapshot testing into two checkers to fix row count mismatch
failures in chaos tests
- **SnapshotChecker** (`Op.snapshot`): lightweight, shares collection
with other checkers, only verifies snapshot create/restore operations
succeed
- **SnapshotRestoreChecker** (`Op.restore_snapshot`): uses independent
collection with internal DML operations, verifies data correctness (row
count + PK) after restore
- Removed `_snapshot_lock` from `Checker` class and all DML checkers
(Insert/Upsert/Delete) to eliminate coupling
## Root Cause
The `SnapshotRestoreChecker` shared a collection with other concurrent
checkers and relied on a global `_snapshot_lock` to prevent data
modifications during snapshot creation. However, some code paths (e.g.,
`Checker.insert_data()` base method,
`DeleteChecker.update_delete_expr()` refill logic) bypassed the lock,
causing row count mismatches after restore. The delta was exactly 3000
(`DELTA_PER_INS`).
Failure log: `expected=158188, actual=155188` (delta=3000)
ref:
https://qa-jenkins.milvus.io/blue/organizations/jenkins/chaos-test-cron/detail/chaos-test-cron/23943/pipeline
## Test plan
- [ ] Run chaos-test-cron pipeline and verify `Op.snapshot` (shared
collection) passes
- [ ] Verify `Op.restore_snapshot` (independent collection) passes with
no row count mismatch
- [ ] Confirm other checkers (insert/upsert/delete) are not impacted by
lock removal
Signed-off-by: zhuwenxing <wenxing.zhu@zilliz.com>
## Summary
Add 6 new test cases to `test_milvus_client_collection.py` covering gaps
in nullable vector field test coverage, identified after verifying fixes
for #47065 and #47197.
**Related issue**: #47846
### New Test Cases
| Test | Level | Coverage |
|------|-------|----------|
| `test_milvus_client_search_all_null_vectors` | L1 | Search on 100%
null vectors (sealed + growing) |
| `test_milvus_client_search_iterator_null_vector` | L1 | Search
iterator with all-null and mixed data |
| `test_milvus_client_query_iterator_null_vector` | L1 | Query iterator
returns all rows including null vectors |
| `test_milvus_client_upsert_null_vector_transitions` | L1 |
Non-null↔null transitions via upsert |
| `test_milvus_client_multi_vector_output_null` | L1 | Multi-vector
output with nullable field |
| `test_milvus_client_compact_with_null_vector` | L2 | Data integrity
after compaction with null vectors |
### Test Plan
- [x] All 6 tests passed against Milvus 2.6.6 (10.104.17.170)
- [x] No regressions in existing null vector tests
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Signed-off-by: yanliang567 <82361606+yanliang567@users.noreply.github.com>
## Summary
- After schema evolution (adding a static column that previously existed
as a dynamic field in `$meta`), partial update (`upsert` with
`partial_update=True`) fails with: `dynamic field name cannot include
the static field name`
- Root cause: during partial update, `queryPreExecute()` fetches
existing data where `$meta` still contains the old dynamic key. After
merging, `verifyDynamicFieldData()` rejects it because the key now
matches a static field name
- Fix: after the merge step in `queryPreExecute()`, strip any keys from
`$meta` JSON that conflict with current static field names
## Test plan
- [x] Added Go unit test
`TestUpsertTask_queryPreExecute_CleanUpMetaAfterSchemaEvolution`
- [x] Added Python e2e test
`test_milvus_client_partial_update_after_schema_evolution_dynamic_to_static`
issue: #47717🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Signed-off-by: Eric Hou <eric.hou@zilliz.com>
Co-authored-by: Eric Hou <eric.hou@zilliz.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Issue: #47548
On branch feature/search-order
Changes to be committed:
new file: milvus_client/test_milvus_client_search_order.py
---------
Signed-off-by: Eric Hou <eric.hou@zilliz.com>
Co-authored-by: Eric Hou <eric.hou@zilliz.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Related to #44452
Remove the deprecated lazy load feature which has been superseded by
warmup-related parameters. This cleanup includes:
- Remove AddFieldDataInfoForSealed from C++ segcore layer
- Remove IsLazyLoad() method and isLazyLoad field from segment
- Remove lazy load checks in proxy alterCollectionTask
- Remove DiskCache lazy load handling in search/retrieve paths
- Remove LazyLoadEnableKey constant and related helper functions
- Update mock files to reflect interface changes
---------
Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
## Summary
- Restructure `TestMilvusClientTimestamptz` to use a shared collection
with non-overlapping PK ranges, reducing test setup overhead
- Add query verification to `test_partial_update` to assert timestamps
are correctly updated
- Separate test data into isolated PK slots to prevent cross-test
interference
Issue: #47668
## Test plan
- [x] Run timestamptz e2e tests to verify all cases pass
- [x] Verify partial update test now properly asserts query results
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Signed-off-by: Eric Hou <eric.hou@zilliz.com>
Co-authored-by: Eric Hou <eric.hou@zilliz.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Summary
Move snapshot existence checks to occur after acquiring exclusive locks
in CreateSnapshot and DropSnapshot. This ensures that when multiple
concurrent requests attempt to create snapshots with the same name, only
one succeeds and others immediately fail with "already exists" error,
allowing DDL callbacks to handle the result properly without entering
infinite retry loops.
## Related Issue
issue: #47101
## Changes
- **CreateSnapshot**: Move snapshot name existence check to after lock
acquisition
- **DropSnapshot**: Move snapshot existence check to after lock
acquisition
- **Test**: Fix concurrent snapshot creation test to verify "already
exists" errors by directly calling client methods to bypass
ResponseChecker framework masking
## Test Plan
- ✅ Unit test: `test_snapshot_concurrent_create_same_name` passes
consistently
- ✅ Verified concurrent behavior: 1 success + 4 "already exists" errors
- ✅ No race conditions observed across multiple test runs
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Signed-off-by: Wei Liu <wei.liu@zilliz.com>
issue: https://github.com/milvus-io/milvus/pull/39803
When creating an index, WarmupKey is removed from TypeParams before
storage (in index_service.go). However, checkParams function was not
filtering WarmupKey when comparing TypeParams for idempotency check,
causing the second CreateIndex call to fail with "at most one distinct
index is allowed per field" error.
This fix adds WarmupKey to the DeleteParams filter in checkParams
function, ensuring consistent behavior with index creation and proper
idempotency.
Signed-off-by: wangting0128 <ting.wang@zilliz.com>
## Summary
Add comprehensive e2e test cases for PR #47333 which fixed three-valued
logic issues in expression evaluation with NULL values.
### Test Coverage (19 cases)
**TestMilvusClientThreeValuedLogic (17 tests)**
- **Basic IS NULL / IS NOT NULL** (2 tests)
- **NOT operator equivalences** - `NOT (IS NOT NULL) == IS NULL` (2
tests)
- **Multiple NOT operations** - double/triple NOT (2 tests)
- **Multi-field NULL combinations** - AND/OR with two nullable fields (2
tests)
- **De Morgan's law** - `NOT (A AND B)`, `NOT (A OR B)` (2 tests)
- **NULL with value comparisons** - combined NULL check and value filter
(3 tests)
- **Mixed filters** - id filter + NULL check (2 tests)
- **Search API** - search with NULL filter expressions (2 tests)
**TestMilvusClientThreeValuedLogicIssue46972 (2 tests)**
- Complex JSON expressions that triggered "False OR False = True" bug
- Uses exact reproduction case from issue #46972
### Test Design
- Uses shared collection pattern for efficiency
- Expected values calculated dynamically from stored data (not
hardcoded)
- Easy to extend with new test cases
### Verification
| Server | Result |
|--------|--------|
| With fix (master) | **19 passed** |
| Without fix (pre-PR#47333) | Multiple failures reproducing the bug |
issue: #46820, #46972🤖 Generated with [Claude Code](https://claude.ai/code)
---------
Signed-off-by: yanliang567 <yanliang.qiao@zilliz.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
## Summary
This PR enhances the Python test log filter plugin to properly
distinguish between xfail and xpass test outcomes, which were previously
not categorized separately.
- **xfail**: Tests marked with `@pytest.mark.xfail` that failed as
expected
- **xpass**: Tests marked with `@pytest.mark.xfail` that passed
unexpectedly (needs attention)
Related to #47253
## Changes
- Detect xfail/xpass using pytest's `wasxfail` attribute
- Add `xfail` and `xpass` categories to `test_stats` tracking
- Update JSON report with xfail/xpass in summary and tests sections
- Update HTML report with:
- New summary cards for xfail (purple) and xpass (pink)
- XPass section with full logs (since unexpected passes need
investigation)
- XFail section with reason only (expected behavior, just tracking)
- Support parallel test runs with worker data merging for xfail/xpass
## Test plan
- [x] Python syntax validation passes
- [ ] Run tests with xfail markers to verify correct categorization
- [ ] Verify JSON report contains xfail/xpass sections
- [ ] Verify HTML report displays xfail/xpass with correct styling
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Signed-off-by: yanliang567 <yanliang.qiao@zilliz.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
## Summary
- Enable search by ids tests that were commented out pending fix of
#47065
- Fix syntax error in test: `for i in len()` → `for i in range(len())`
- Update test expectations to match the fixed behavior:
- Search on null vectors now returns empty results instead of error
- Fix assertion to use correct `num_entities_with_not_null_vector` count
## Test plan
- [x] `test_milvus_client_add_nullable_vector_field_search` - verified
passing
- [x] `test_milvus_client_collection_null_vector_field_search` -
verified passing
issue: #47065🤖 Generated with [Claude Code](https://claude.ai/code)
---------
Signed-off-by: Yan Liang <yanliang@zilliz.com>
Signed-off-by: yanliang567 <yanliang.qiao@zilliz.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
## Summary
- Add mock TEI server utility (`common/mock_tei_server.py`) for testing
text embedding functions
- Add test cases for PR #46984 fix (alter function when other function
is invalid)
## Test Cases
1. `test_alter_function_when_other_function_is_invalid` - Verify that
altering a valid function succeeds even when another function in the
collection is invalid
2. `test_alter_invalid_function_to_valid_endpoint` - Verify that users
can fix an invalid function by altering it to a valid endpoint
## Related Issues
- Issue: https://github.com/milvus-io/milvus/issues/46949
- Fix PR: https://github.com/milvus-io/milvus/pull/46984
## Test Plan
- [x] Verified test fails with unfixed Milvus
(`master-20260112-7bcd3b10`)
- [x] Verified test passes with fixed Milvus (`master-20260112-b39ecb0`)
---------
Signed-off-by: zhuwenxing <wenxing.zhu@zilliz.com>
## Summary
- Add `SnapshotRestoreChecker` to test snapshot restore functionality in
chaos testing
- Support concurrent execution with other checkers (shared collection)
- Use `self.get_schema()` to get latest schema for DML operations
- Simplified data verification for concurrent scenarios
## Test plan
- [x] Single run test passed
- [x] Concurrent operation test passed (100% success rate)
- [x] Added to test_concurrent_operation.py
- [x] Added to test_single_request_operation.py
---------
Signed-off-by: zhuwenxing <wenxing.zhu@zilliz.com>
## Summary
- Add comprehensive test cases for Milvus snapshot API functionality
- Cover snapshot create, list, describe, drop, restore operations
- Test various data types, index types, partition scenarios
- Add concurrent operation and data integrity tests
- Update pymilvus to 2.7.0rc122 for snapshot API support
## Test Coverage
- L0 smoke tests: basic snapshot lifecycle
- L1 tests: data types, partitions, indexes
- L2 tests: boundary conditions, negative cases, concurrency
## Related Issue
https://github.com/milvus-io/milvus/issues/44358
## Test plan
- [x] Run tests with `-n 6` parallel execution
- [x] Verify all tests pass (67 tests: 62 passed, 4 xfail)
---------
Signed-off-by: zhuwenxing <wenxing.zhu@zilliz.com>