|
|
@@ -583,8 +583,13 @@ func TestSkippedIndexDoesNotKillTable(t *testing.T) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-// TestRunRejectsSelfMigration 源和目标指向同一个库必须拦住 —— 否则边读边写会把
|
|
|
-// 表毁掉。
|
|
|
+// TestRunRejectsSelfMigration 两件事:
|
|
|
+// 1. 锁语义: 同一路径的第二次打开必须被文件锁拒绝 (跨进程与同进程其它句柄
|
|
|
+// 一视同仁 —— 引擎只允许一个实例操作一个库);
|
|
|
+// 2. Run 的自我迁移闸门: 同一句柄同时作为源与目标必须被拒 (迁移前检查,
|
|
|
+// 不做任何 I/O)。
|
|
|
+// 旧实现靠"同进程双开同一文件"搭场景, 而双开正是锁禁止的行为 —— 闸门本身
|
|
|
+// 用同一句柄传两遍即可验证, 不再依赖双开。
|
|
|
func TestRunRejectsSelfMigration(t *testing.T) {
|
|
|
dir := t.TempDir()
|
|
|
path := filepath.Join(dir, "same.db")
|
|
|
@@ -595,13 +600,14 @@ func TestRunRejectsSelfMigration(t *testing.T) {
|
|
|
t.Fatal(err)
|
|
|
}
|
|
|
defer a.Close()
|
|
|
- b, err := OpenVRTX(path, quiet())
|
|
|
- if err != nil {
|
|
|
- t.Fatal(err)
|
|
|
+
|
|
|
+ // 1) 锁: 同路径第二次打开 (同进程第二个句柄) 必须报 ErrDatabaseLocked
|
|
|
+ if _, err := OpenVRTX(path, quiet()); !errors.Is(err, core.ErrDatabaseLocked) {
|
|
|
+ t.Fatalf("同路径第二次打开应报 ErrDatabaseLocked, 实际: %v", err)
|
|
|
}
|
|
|
- defer b.Close()
|
|
|
|
|
|
- if _, err := Run(a, b, quiet()); err == nil {
|
|
|
+ // 2) 自我迁移: Run 在迁移前按 Identity 拦截
|
|
|
+ if _, err := Run(a, a, quiet()); err == nil {
|
|
|
t.Fatal("同一个库的自我迁移应当报错")
|
|
|
}
|
|
|
}
|