mirror of
https://github.com/milvus-io/milvus.git
synced 2026-07-21 02:05:41 +00:00
test: add snapshot lifecycle, alias, and cross-db test cases (#47840)
## Summary - Add 15 new test cases for snapshot feature covering lifecycle edge cases, alias support, and cross-database restore - Verify fix for #47578 (DropSnapshot during active restore) - All tests verified on latest master image (`master-20260224-091b147e-amd64`) ### New Test Classes | Class | Tests | Level | Description | |-------|-------|-------|-------------| | `TestMilvusClientSnapshotDropInvalid` | +1 | L1 | Drop during active restore (#47578) | | `TestMilvusClientSnapshotLifecycle` | +8 | L2/L3 | Collection lifecycle + snapshot interactions | | `TestMilvusClientSnapshotAlias` | +6 | L2 | Snapshot ops via collection aliases | ### Test Details **Lifecycle tests (L2):** - Drop target collection during restore - Rename source collection after snapshot creation - Create snapshot on collection being restored to - Restore failure leaves no resource leak - Concurrent drop of same snapshot (idempotent) - Create snapshot during drop of source collection - Cross-database snapshot restore - Drop and restore race condition (L3) **Alias tests (L2):** - Create snapshot via alias → describe shows real collection name - List snapshots via alias == list via real name - Restore from alias-created snapshot with data integrity - List restore jobs via alias on restored collection - Dropped alias → create snapshot fails with "not found" - Alter alias retarget → list snapshots reflects new target ## Test plan - [x] All 14 L1/L2 tests pass on standalone (master-20260224-091b147e-amd64) - [x] L3 race test works but may timeout on standalone due to resource exhaustion --------- Signed-off-by: zhuwenxing <wenxing.zhu@zilliz.com> Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
fab6c33dce
commit
e91e8825f7
@@ -0,0 +1,95 @@
|
||||
# tests/Makefile — lint helpers for Python files under tests/.
|
||||
#
|
||||
# All targets operate on the *PR-changed* set: files under tests/**/*.py that
|
||||
# differ between $(BASE_REF) and HEAD (three-dot diff = since merge-base),
|
||||
# matching the GitHub Actions "Python Lint (tests/)" workflow.
|
||||
#
|
||||
# Usage (run from this tests/ directory):
|
||||
# make lint # ruff check (CI equivalent)
|
||||
# make format-check # ruff format --check (CI equivalent)
|
||||
# make ci # lint + format-check
|
||||
# make lint-fix # ruff check --fix
|
||||
# make format # ruff format
|
||||
#
|
||||
# Variables:
|
||||
# BASE_REF diff base ref. Auto-detected from the current branch's open PR
|
||||
# via `gh pr view`. If no PR exists, you MUST set it explicitly,
|
||||
# e.g.: make ci BASE_REF=origin/master
|
||||
# RUFF_VERSION ruff version (default: 0.15.11, pinned to .github/workflows/python-lint.yaml)
|
||||
#
|
||||
# Requires `uvx` (ships with `uv`). Ruff is fetched & cached on first run.
|
||||
# Auto-detection requires `gh` authenticated (`gh auth status`).
|
||||
|
||||
RUFF_VERSION ?= 0.15.11
|
||||
RUFF := uvx ruff@$(RUFF_VERSION)
|
||||
REPO_ROOT := $(shell git rev-parse --show-toplevel)
|
||||
|
||||
# Auto-detect the base ref from the current branch's open PR.
|
||||
# Steps:
|
||||
# 1. Read the PR URL (always lives under the base repo) and base branch via gh.
|
||||
# Extract base repo as "<owner>/<name>" from the URL path.
|
||||
# 2. Find which local remote points to that base repo (must NOT assume "origin"
|
||||
# — for forks, "upstream" is typically the base; for direct clones, "origin").
|
||||
# 3. Emit "<remote>/<baseRefName>".
|
||||
# Empty when no PR exists, no remote matches, or gh is unauthenticated —
|
||||
# user must then set BASE_REF explicitly.
|
||||
BASE_REF ?= $(shell \
|
||||
pr_url=$$(gh pr view --json url -q .url 2>/dev/null); \
|
||||
base_branch=$$(gh pr view --json baseRefName -q .baseRefName 2>/dev/null); \
|
||||
if [ -z "$$pr_url" ] || [ -z "$$base_branch" ]; then exit 0; fi; \
|
||||
base_repo=$$(echo "$$pr_url" | sed -E 's|^https?://[^/]+/([^/]+/[^/]+)/.*|\1|'); \
|
||||
if [ -z "$$base_repo" ]; then exit 0; fi; \
|
||||
remote=$$(git -C $(REPO_ROOT) remote -v | awk -v p="$$base_repo" 'index($$2, p) > 0 && $$3=="(fetch)" {print $$1; exit}'); \
|
||||
if [ -z "$$remote" ]; then exit 0; fi; \
|
||||
echo "$$remote/$$base_branch")
|
||||
|
||||
CHANGED_FILES_CMD = git -C $(REPO_ROOT) diff --name-only --diff-filter=ACMR $(BASE_REF)...HEAD -- 'tests/**/*.py'
|
||||
|
||||
.PHONY: help lint format-check ci lint-fix format _require-base-ref
|
||||
|
||||
help:
|
||||
@echo "tests/ Makefile — lint PR-changed *.py using ruff $(RUFF_VERSION)"
|
||||
@echo
|
||||
@echo "Targets:"
|
||||
@echo " make lint ruff check (CI equivalent)"
|
||||
@echo " make format-check ruff format --check (CI equivalent)"
|
||||
@echo " make ci lint + format-check"
|
||||
@echo " make lint-fix ruff check --fix"
|
||||
@echo " make format ruff format"
|
||||
@echo
|
||||
@echo "BASE_REF: auto-detected from the current branch's open PR via 'gh pr view'."
|
||||
@echo " When no PR exists, you must set it explicitly:"
|
||||
@echo " make ci BASE_REF=origin/master"
|
||||
@if [ -n "$(BASE_REF)" ]; then echo; echo "Currently detected: BASE_REF=$(BASE_REF)"; \
|
||||
else echo; echo "Currently: BASE_REF is unset (no open PR detected)."; fi
|
||||
|
||||
_require-base-ref:
|
||||
@if [ -z "$(BASE_REF)" ]; then \
|
||||
echo "Error: BASE_REF is not set."; \
|
||||
echo " No open PR detected for the current branch via 'gh pr view'."; \
|
||||
echo " Set it explicitly, e.g.:"; \
|
||||
echo " make $(or $(MAKECMDGOALS),ci) BASE_REF=origin/master"; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
lint: _require-base-ref
|
||||
@files=$$($(CHANGED_FILES_CMD)); \
|
||||
if [ -z "$$files" ]; then echo "No changed Python files under tests/ (base: $(BASE_REF))."; \
|
||||
else cd $(REPO_ROOT) && $(RUFF) check $$files; fi
|
||||
|
||||
format-check: _require-base-ref
|
||||
@files=$$($(CHANGED_FILES_CMD)); \
|
||||
if [ -z "$$files" ]; then echo "No changed Python files under tests/ (base: $(BASE_REF))."; \
|
||||
else cd $(REPO_ROOT) && $(RUFF) format --check --diff $$files; fi
|
||||
|
||||
ci: lint format-check
|
||||
|
||||
lint-fix: _require-base-ref
|
||||
@files=$$($(CHANGED_FILES_CMD)); \
|
||||
if [ -z "$$files" ]; then echo "No changed Python files under tests/ (base: $(BASE_REF))."; \
|
||||
else cd $(REPO_ROOT) && $(RUFF) check --fix $$files; fi
|
||||
|
||||
format: _require-base-ref
|
||||
@files=$$($(CHANGED_FILES_CMD)); \
|
||||
if [ -z "$$files" ]; then echo "No changed Python files under tests/ (base: $(BASE_REF))."; \
|
||||
else cd $(REPO_ROOT) && $(RUFF) format $$files; fi
|
||||
@@ -108,3 +108,38 @@ $ uv run ruff format --check . # format check only (CI-friendly)
|
||||
|
||||
Rules enabled: `E`, `F`, `W`, `I`, `UP`. Target Python version: `3.10`.
|
||||
|
||||
#### Lint only PR-changed files (Python Lint CI parity)
|
||||
|
||||
The GitHub Actions workflow `.github/workflows/python-lint.yaml` (job
|
||||
**"Python Lint (tests/) / Ruff (changed files only)"**) runs `ruff check`
|
||||
and `ruff format --check` against the *changed* `tests/**/*.py` set on
|
||||
every PR. Running `uv run ruff check .` over the whole tree is too coarse
|
||||
because the historical contents of many files predate the lint config and
|
||||
will fail unrelated rules.
|
||||
|
||||
To reproduce the CI step locally, use the `Makefile` shipped in this directory:
|
||||
|
||||
```shell
|
||||
$ cd tests/
|
||||
$ make ci # ruff check + format --check on PR-changed *.py (CI equivalent)
|
||||
$ make lint-fix # ruff check --fix on PR-changed *.py
|
||||
$ make format # ruff format on PR-changed *.py
|
||||
$ make help # show all targets and the detected BASE_REF
|
||||
```
|
||||
|
||||
`BASE_REF` is auto-detected from the current branch's open PR via `gh pr view`:
|
||||
the PR URL is parsed to discover the base `<owner>/<repo>` and matched against
|
||||
your local git remotes, producing e.g. `upstream/master`, `upstream/2.x`, or
|
||||
`origin/main` for direct clones.
|
||||
|
||||
If no open PR exists for the branch, you **must** set `BASE_REF` explicitly
|
||||
(no guessing — a wrong base diffs against unrelated commits):
|
||||
|
||||
```shell
|
||||
$ make ci BASE_REF=upstream/master
|
||||
```
|
||||
|
||||
Requires `uv` (provides `uvx`) and `gh` authenticated against GitHub
|
||||
(`gh auth status`). The ruff version is pinned in the `Makefile` via
|
||||
`RUFF_VERSION` to match the workflow.
|
||||
|
||||
|
||||
@@ -108,3 +108,37 @@ $ uv run ruff format --check . # 只检查不修改 (CI 友好)
|
||||
|
||||
启用的规则:`E`、`F`、`W`、`I`、`UP`;目标 Python 版本:`3.10`。
|
||||
|
||||
#### 仅检查 PR 修改的文件 (与 Python Lint CI 一致)
|
||||
|
||||
GitHub Actions workflow `.github/workflows/python-lint.yaml`
|
||||
(job **"Python Lint (tests/) / Ruff (changed files only)"**)
|
||||
只对 PR 修改的 `tests/**/*.py` 文件跑 `ruff check` 和 `ruff format --check`。
|
||||
直接对整个 `tests/` 目录执行 `uv run ruff check .` 太粗——很多历史文件早于
|
||||
当前 lint 配置,会因为无关规则失败。
|
||||
|
||||
要在本地复现 CI 这一步,使用本目录下的 `Makefile`:
|
||||
|
||||
```shell
|
||||
$ cd tests/
|
||||
$ make ci # 对 PR 修改文件跑 ruff check + format --check(与 CI 等价)
|
||||
$ make lint-fix # 对 PR 修改文件跑 ruff check --fix
|
||||
$ make format # 对 PR 修改文件跑 ruff format
|
||||
$ make help # 显示所有 target 以及当前自动检测到的 BASE_REF
|
||||
```
|
||||
|
||||
`BASE_REF` 通过 `gh pr view` 从当前分支的开放 PR 中自动检测:
|
||||
解析 PR URL 得到 base `<owner>/<repo>`,再匹配本地 git remotes,
|
||||
得到形如 `upstream/master`、`upstream/2.x` 或(直接 clone 主仓库时的)
|
||||
`origin/main`。
|
||||
|
||||
如果当前分支没有开放 PR,**必须**显式设置 `BASE_REF`
|
||||
(不再做猜测——base 选错会 diff 出无关 commit):
|
||||
|
||||
```shell
|
||||
$ make ci BASE_REF=upstream/master
|
||||
```
|
||||
|
||||
需要本地已安装 `uv`(提供 `uvx`)和已认证的 `gh`
|
||||
(`gh auth status`)。Makefile 通过 `RUFF_VERSION` 锁定与
|
||||
workflow 一致的 ruff 版本。
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user