CI / verify (push) Canceled after 0s
Docker Release / build-and-push (amd64, linux/amd64) (push) Canceled after 0s
Docker Release / build-and-push (arm64, linux/arm64) (push) Canceled after 0s
GitHub Release / release (push) Canceled after 0s
Docker Release / create-manifest (push) Canceled after 0s
- 「公网服务端」新增 Nginx 启停控制(Agent 0.15.2,停止带二次确认) - frps 启动失败不再误报成功,并增强启动诊断 - frps vhost 端口禁止 80/443,避免与 VPS 上 Nginx 冲突 - 旧服务端配置的 tcp_mux / login_fail_exit 默认值补齐 - 新增安全审查、页面布局方案与场景操作文档
107 lines
3.7 KiB
Go
107 lines
3.7 KiB
Go
package frp
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestDiagnoseDialError(t *testing.T) {
|
|
err := errors.New("connectex: An attempt was made to access a socket in a way forbidden by its access permissions.")
|
|
message := diagnoseDialError(err)
|
|
if !strings.HasPrefix(message, "本机网络策略阻止连接:") {
|
|
t.Fatalf("unexpected message: %s", message)
|
|
}
|
|
}
|
|
|
|
// 23.3:诊断拆分为独立检查项,登录状态从 frpc 日志推断,unknown 不等于失败。
|
|
func TestSummarizeFRPCLogin(t *testing.T) {
|
|
logLines := strings.Join([]string{
|
|
"2026/09/17 10:00:00 [I] [root.go:139] frpc service start",
|
|
"2026/09/17 10:00:01 [W] [control.go:167] login to the server failed: token error",
|
|
"2026/09/17 10:01:00 [I] [control.go:164] login to server success, get run id [abc]",
|
|
}, "\n")
|
|
state, detail := summarizeFRPCLogin(logLines)
|
|
if state != diagStateOK {
|
|
t.Fatalf("login success should win over earlier failure, got %s (%s)", state, detail)
|
|
}
|
|
failedLog := "2026/09/17 10:00:01 [W] [control.go:167] login to the server failed: token [wrong] error: authentication failed"
|
|
state, detail = summarizeFRPCLogin(failedLog)
|
|
if state != diagStateFailed || !strings.Contains(detail, "登录失败") {
|
|
t.Fatalf("login failure should be reported, got %s (%s)", state, detail)
|
|
}
|
|
state, _ = summarizeFRPCLogin("2026/09/17 10:00:00 [I] [root.go:139] frpc service start")
|
|
if state != diagStateUnknown {
|
|
t.Fatalf("no login evidence should be unknown, got %s", state)
|
|
}
|
|
}
|
|
|
|
func TestDiagnoseDNSFormatsRecords(t *testing.T) {
|
|
check := diagnoseDNS(context.Background(), "192.168.1.10")
|
|
if check.State != diagStateOK || !strings.Contains(check.Detail, "IP 地址") {
|
|
t.Fatalf("literal IP should skip resolution: %+v", check)
|
|
}
|
|
}
|
|
|
|
func TestSummarizeServerSamplesUsesLatestStatus(t *testing.T) {
|
|
detail := summarizeServerSamples([]ServerSample{
|
|
{CheckedAt: "2026-09-15 18:00:00", Available: true, LatencyMS: 20},
|
|
{CheckedAt: "2026-09-15 18:01:00", Available: false, Error: "连接失败"},
|
|
})
|
|
if detail.Available {
|
|
t.Fatal("latest failed sample should make current status unavailable")
|
|
}
|
|
if detail.Availability != 50 {
|
|
t.Fatalf("unexpected availability: %v", detail.Availability)
|
|
}
|
|
if detail.AverageLatency != 20 || detail.PeakLatency != 20 {
|
|
t.Fatalf("unexpected latency summary: average=%d peak=%d", detail.AverageLatency, detail.PeakLatency)
|
|
}
|
|
if detail.LastError != "连接失败" {
|
|
t.Fatalf("unexpected last error: %s", detail.LastError)
|
|
}
|
|
}
|
|
|
|
func TestSSHSettingsChanged(t *testing.T) {
|
|
base := Server{SSHHost: "vps-a.example.com", SSHPort: 22, SSHUser: "root", SSHAuth: "key"}
|
|
if sshSettingsChanged(base, base, false) {
|
|
t.Fatal("相同 SSH 配置不应判定为变化")
|
|
}
|
|
cases := []Server{
|
|
{SSHHost: "vps-b.example.com", SSHPort: 22, SSHUser: "root", SSHAuth: "key"},
|
|
{SSHHost: "vps-a.example.com", SSHPort: 2222, SSHUser: "root", SSHAuth: "key"},
|
|
{SSHHost: "vps-a.example.com", SSHPort: 22, SSHUser: "admin", SSHAuth: "key"},
|
|
{SSHHost: "vps-a.example.com", SSHPort: 22, SSHUser: "root", SSHAuth: "password"},
|
|
}
|
|
for _, updated := range cases {
|
|
if !sshSettingsChanged(base, updated, false) {
|
|
t.Fatalf("SSH 配置变化未识别: %+v", updated)
|
|
}
|
|
}
|
|
if !sshSettingsChanged(base, base, true) {
|
|
t.Fatal("SSH 凭据更新应判定为变化")
|
|
}
|
|
}
|
|
|
|
func TestIsLoopbackAgentURL(t *testing.T) {
|
|
for _, raw := range []string{
|
|
"http://127.0.0.1:17700",
|
|
"http://localhost:17700",
|
|
"https://[::1]:17700",
|
|
} {
|
|
if !isLoopbackAgentURL(raw) {
|
|
t.Fatalf("%q 应识别为回环地址", raw)
|
|
}
|
|
}
|
|
for _, raw := range []string{
|
|
"http://38.95.74.87:7700",
|
|
"https://agent.example.com",
|
|
"",
|
|
} {
|
|
if isLoopbackAgentURL(raw) {
|
|
t.Fatalf("%q 不应识别为回环地址", raw)
|
|
}
|
|
}
|
|
}
|