Files
mrlee 302248a907
CI / verify (push) Canceled after 0s
chore(release): 发布 v2.0.0
- 内置 SSH 终端(/terminal):复用已保存的 SSH 密码/私钥与独立 known_hosts 校验
- 终端二次认证、会话审计(/terminal/audits)、录像审计与常用命令
- DDNS 服务商名称与自定义 IP,新增迁移 037/038/039
- CHANGELOG 与 VERSION 更新至 2.0.0
2026-10-16 20:18:04 +08:00

89 lines
2.7 KiB
Go

package agent
import (
"net"
"net/http"
"net/http/httptest"
"sync/atomic"
"testing"
"time"
)
// 用临时参数跑探测,避免单测真的等满默认的 1.5 秒间隔
func stubProbeRetry(t *testing.T, attempts int) {
t.Helper()
oldAttempts, oldInterval := routeProbeAttempts, routeProbeInterval
routeProbeAttempts, routeProbeInterval = attempts, time.Millisecond
t.Cleanup(func() { routeProbeAttempts, routeProbeInterval = oldAttempts, oldInterval })
}
func probePort(t *testing.T, server *httptest.Server) int {
t.Helper()
addr, ok := server.Listener.Addr().(*net.TCPAddr)
if !ok {
t.Fatalf("无法取到测试服务端口:%v", server.Listener.Addr())
}
return addr.Port
}
// TestProbeVhostReadyWaitsForRegistration:前两次 404(隧道尚未注册)后应继续重试并拿到 200,
// 这正是「部署后立刻探测误报失败、刷新又正常」的场景。
func TestProbeVhostReadyWaitsForRegistration(t *testing.T) {
stubProbeRetry(t, 4)
var hits int32
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
if atomic.AddInt32(&hits, 1) <= 2 {
w.WriteHeader(http.StatusNotFound)
return
}
w.WriteHeader(http.StatusOK)
}))
defer server.Close()
code, _ := (&Server{}).probeVhostReady(probePort(t, server), "a.example.com")
if code != http.StatusOK {
t.Fatalf("期望重试后拿到 200,实际 %d", code)
}
if hits != 3 {
t.Fatalf("期望探测 3 次后成功,实际 %d 次", hits)
}
}
// TestProbeVhostReadyStopsOnSuccess:非 404 立即返回,不做多余重试。
func TestProbeVhostReadyStopsOnSuccess(t *testing.T) {
stubProbeRetry(t, 4)
var hits int32
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
atomic.AddInt32(&hits, 1)
w.WriteHeader(http.StatusBadGateway)
}))
defer server.Close()
code, _ := (&Server{}).probeVhostReady(probePort(t, server), "a.example.com")
if code != http.StatusBadGateway {
t.Fatalf("期望原样返回 502,实际 %d", code)
}
if hits != 1 {
t.Fatalf("502 不应重试,实际探测 %d 次", hits)
}
}
// TestProbeVhostReadyGivesUpAfterAttempts:一直 404 时用尽重试次数并返回最后一次结果。
func TestProbeVhostReadyGivesUpAfterAttempts(t *testing.T) {
stubProbeRetry(t, 3)
var hits int32
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
atomic.AddInt32(&hits, 1)
w.WriteHeader(http.StatusNotFound)
}))
defer server.Close()
code, _ := (&Server{}).probeVhostReady(probePort(t, server), "a.example.com")
if code != http.StatusNotFound {
t.Fatalf("期望最终仍为 404,实际 %d", code)
}
if hits != 3 {
t.Fatalf("期望探测 3 次后放弃,实际 %d 次", hits)
}
}