新增功能: - stream 模块: 流式传输支持,优化大文件和实时数据传输 - Goroutine 池: 限制并发数量,减少调度开销 - 优雅升级: 零停机热升级,继承父进程监听器 - sendfile: 零拷贝文件传输,大文件直接从内核传输 重构改进: - App 结构体封装,支持热升级和信号处理 - 配置结构字段对齐和代码清理 - 完善错误处理和日志记录 Co-Authored-By: Claude <noreply@anthropic.com>
101 lines
2.1 KiB
Go
101 lines
2.1 KiB
Go
package server
|
|
|
|
import (
|
|
"os"
|
|
"testing"
|
|
)
|
|
|
|
func TestNewUpgradeManager(t *testing.T) {
|
|
srv := New(nil)
|
|
mgr := NewUpgradeManager(srv)
|
|
|
|
if mgr == nil {
|
|
t.Error("Expected non-nil manager")
|
|
}
|
|
if mgr.server != srv {
|
|
t.Error("Expected server to be set")
|
|
}
|
|
}
|
|
|
|
func TestIsChild(t *testing.T) {
|
|
mgr := NewUpgradeManager(nil)
|
|
|
|
// 默认不是子进程
|
|
if mgr.IsChild() {
|
|
t.Error("Expected IsChild to be false by default")
|
|
}
|
|
|
|
// 设置环境变量
|
|
os.Setenv("GRACEFUL_UPGRADE", "1")
|
|
defer os.Unsetenv("GRACEFUL_UPGRADE")
|
|
|
|
if !mgr.IsChild() {
|
|
t.Error("Expected IsChild to be true when GRACEFUL_UPGRADE=1")
|
|
}
|
|
}
|
|
|
|
func TestPidFile(t *testing.T) {
|
|
tmpFile := "/tmp/lolly-test.pid"
|
|
defer os.Remove(tmpFile)
|
|
|
|
mgr := NewUpgradeManager(nil)
|
|
mgr.SetPidFile(tmpFile)
|
|
|
|
// 写入 PID
|
|
if err := mgr.WritePid(); err != nil {
|
|
t.Errorf("WritePid failed: %v", err)
|
|
}
|
|
|
|
// 读取 PID
|
|
pid, err := mgr.ReadOldPid()
|
|
if err != nil {
|
|
t.Errorf("ReadOldPid failed: %v", err)
|
|
}
|
|
if pid != os.Getpid() {
|
|
t.Errorf("Expected pid %d, got %d", os.Getpid(), pid)
|
|
}
|
|
}
|
|
|
|
func TestReadOldPidNoFile(t *testing.T) {
|
|
mgr := NewUpgradeManager(nil)
|
|
mgr.SetPidFile("/nonexistent/path/pid")
|
|
|
|
_, err := mgr.ReadOldPid()
|
|
if err == nil {
|
|
t.Error("Expected error for non-existent file")
|
|
}
|
|
}
|
|
|
|
func TestGetInheritedListenersNoFds(t *testing.T) {
|
|
mgr := NewUpgradeManager(nil)
|
|
|
|
// 没有设置 LISTEN_FDS
|
|
listeners, err := mgr.GetInheritedListeners()
|
|
if err != nil {
|
|
t.Errorf("GetInheritedListeners failed: %v", err)
|
|
}
|
|
if len(listeners) != 0 {
|
|
t.Errorf("Expected 0 listeners, got %d", len(listeners))
|
|
}
|
|
}
|
|
|
|
func TestNotifyOldProcessNoPid(t *testing.T) {
|
|
mgr := NewUpgradeManager(nil)
|
|
mgr.SetPidFile("/nonexistent/pid")
|
|
|
|
// 没有 PID 文件,应该返回 nil
|
|
err := mgr.NotifyOldProcess()
|
|
if err != nil {
|
|
t.Errorf("NotifyOldProcess should return nil for no pid, got: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestWaitForShutdownNoOldPid(t *testing.T) {
|
|
mgr := NewUpgradeManager(nil)
|
|
|
|
// 没有旧进程
|
|
err := mgr.WaitForShutdown(0)
|
|
if err != nil {
|
|
t.Errorf("WaitForShutdown should return nil for no old pid, got: %v", err)
|
|
}
|
|
} |