Files
ModelRouter/internal/lua/plugin_unload_test.go
JianFeeeee 6fe6014d92 chore: 清理 emoji 与修正发布脚本仓库名
产品代码统一为纯文本风格(照参考实现),去掉 emoji:billing/quota/usage 插件、
channels 的提示文案、WebUI 文案,以及 go 测试、docs、packaging 脚本中的
注意/OK/FAIL 等符号化写法。第三方目录(vendor、node_modules、.probe)不动。

另:packaging/upload-release.sh 的仓库名改为真实全名
JianFeeeee/ModelRouter → HeNanMU-EEA/ModelRouter(前者是重定向,POST/PUT 不跟随
会 404)。
2026-10-13 13:42:57 +08:00

53 lines
1.7 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package lua
import (
"os/exec"
"testing"
"time"
)
// TestOnUnloadReapsPluginProcesses 验收通用卸载钩子。
//
// 内核职责是"调度插件"——卸载是调度的一部分,而插件可能持有外部资源(进程、
// 文件句柄、远端会话)。内核不知道也不需要知道这些资源是什么;它只要在关闭
// 状态前给插件一次自清理的机会(on_unload),资源归属就始终在插件侧。
// 本测试用"插件起一个进程、卸载时杀掉"来证明这条链路真的闭合。
func TestOnUnloadReapsPluginProcesses(t *testing.T) {
_, ps, _ := runtimePlugins(t)
code := `
local plugin = { name = "reaper", version = "1.0" }
plugin.exports = { "touch" }
local pid = nil
function plugin.touch()
local h = io.popen("sh -c 'sleep 300 & echo $!'")
pid = h:read("*l"); h:close()
return { status = 200, json = { pid = pid } }
end
function plugin.on_unload()
if pid then os.execute("kill -9 " .. pid .. " 2>/dev/null") end
end
return plugin`
if err := ps.LoadSource("reaper", code); err != nil {
t.Fatal(err)
}
out, err := ps.Call("reaper", "touch", map[string]interface{}{})
if err != nil {
t.Fatal(err)
}
m := out.(map[string]interface{})
js := m["json"].(map[string]interface{})
pid := js["pid"].(string)
time.Sleep(300 * time.Millisecond)
if err := exec.Command("kill", "-0", pid).Run(); err != nil {
t.Fatalf("进程应存活: %v", err)
}
if err := ps.Unload("reaper"); err != nil {
t.Fatalf("unload: %v", err)
}
time.Sleep(500 * time.Millisecond)
if err := exec.Command("kill", "-0", pid).Run(); err == nil {
exec.Command("kill", "-9", pid).Run()
t.Fatal("unload 后进程仍存活 —— on_unload 未被调用")
}
}