mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-08-07 15:13:51 +08:00
- 优先等待驱动代理自然退出,超时后再执行强制终止 - 进程已退出时忽略 Windows 终止权限竞态,避免连接成功被误判为失败 - 统一可选驱动与 MySQL agent 清理流程并补充回归测试
74 lines
1.5 KiB
Go
74 lines
1.5 KiB
Go
package db
|
|
|
|
import (
|
|
"errors"
|
|
"sync/atomic"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestWaitForAgentExitIgnoresKillErrorAfterProcessExit(t *testing.T) {
|
|
waitStarted := make(chan struct{})
|
|
processExited := make(chan struct{})
|
|
killErr := errors.New("TerminateProcess: Access is denied")
|
|
|
|
err := waitForAgentExit(
|
|
func() error {
|
|
close(waitStarted)
|
|
<-processExited
|
|
return nil
|
|
},
|
|
func() error {
|
|
<-waitStarted
|
|
close(processExited)
|
|
return killErr
|
|
},
|
|
50*time.Millisecond,
|
|
)
|
|
if err != nil {
|
|
t.Fatalf("process exit should make the racing kill error irrelevant, got %v", err)
|
|
}
|
|
}
|
|
|
|
func TestWaitForAgentExitWaitsBeforeKilling(t *testing.T) {
|
|
var killCalled atomic.Bool
|
|
|
|
err := waitForAgentExit(
|
|
func() error { return nil },
|
|
func() error {
|
|
killCalled.Store(true)
|
|
return nil
|
|
},
|
|
time.Second,
|
|
)
|
|
if err != nil {
|
|
t.Fatalf("graceful process exit returned error: %v", err)
|
|
}
|
|
if killCalled.Load() {
|
|
t.Fatal("process was killed even though it exited during the graceful wait")
|
|
}
|
|
}
|
|
|
|
func TestWaitForAgentExitReturnsKillErrorWhenProcessDoesNotExit(t *testing.T) {
|
|
waitStarted := make(chan struct{})
|
|
processExited := make(chan struct{})
|
|
killErr := errors.New("TerminateProcess: Access is denied")
|
|
|
|
err := waitForAgentExit(
|
|
func() error {
|
|
close(waitStarted)
|
|
<-processExited
|
|
return nil
|
|
},
|
|
func() error {
|
|
<-waitStarted
|
|
return killErr
|
|
},
|
|
20*time.Millisecond,
|
|
)
|
|
close(processExited)
|
|
if !errors.Is(err, killErr) {
|
|
t.Fatalf("expected kill error when the process never exits, got %v", err)
|
|
}
|
|
}
|