yl32940 3 هفته پیش
والد
کامیت
2f504cf451
1فایلهای تغییر یافته به همراه13 افزوده شده و 7 حذف شده
  1. 13 7
      migrate/roundtrip_test.go

+ 13 - 7
migrate/roundtrip_test.go

@@ -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("同一个库的自我迁移应当报错")
 	}
 }