1
0
Files
nex/backend/cmd/desktop/port_test.go
lanyuanxiaoyao 5513f0c13d feat: 区分 server 与 desktop 配置加载入口,取消自动创建配置文件
- config.go 重构:抽取 loadConfig 共享逻辑,新增 LoadServerConfig/LoadDesktopConfig/LoadDesktopConfigAtPath,LoadConfig 保持向后兼容
- setupConfigFile 移除 SafeWriteConfigAs 自动创建逻辑,文件不存在时仅使用默认值
- cmd/desktop 切换为 LoadDesktopConfig,端口/HTTP/浏览器/托盘统一使用 cfg.Server.Port
- cmd/server 显式使用 LoadServerConfig 明确入口语义
- 提取 desktop 可测 helper:desktopListenAddr/desktopURL/desktopPortMenuTitle/desktopConfigErrorMessage
- 新增测试:desktop 忽略 CLI/env/未知参数、配置快照不变、无效配置文件不静默回退、端口 helper 一致性
- README 区分 server/desktop 配置源,移除首次启动自动创建配置文件描述
- 同步 delta specs 到 openspec/specs/ 主规范
2026-05-06 11:59:19 +08:00

130 lines
3.1 KiB
Go
Raw 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 main
import (
"errors"
"net"
"net/http"
"strings"
"testing"
"time"
)
func TestCheckPortAvailable(t *testing.T) {
port := 19826
err := checkPortAvailable(port)
if err != nil {
t.Fatalf("端口 %d 应该可用: %v", port, err)
}
t.Log("端口可用测试通过")
}
func TestCheckPortOccupied(t *testing.T) {
port := 19827
listener, err := net.Listen("tcp", ":19827") //nolint:gosec // 需要验证 checkPortAvailable 对通配地址占用的检测行为
if err != nil {
t.Fatalf("无法启动测试服务器: %v", err)
}
defer listener.Close()
time.Sleep(100 * time.Millisecond)
err = checkPortAvailable(port)
if err == nil {
t.Fatal("端口被占用时应该返回错误")
}
t.Log("端口占用检测测试通过")
}
func TestCheckPortAvailableAfterClose(t *testing.T) {
port := 19828
listener, err := net.Listen("tcp", "127.0.0.1:19828")
if err != nil {
t.Fatalf("无法启动测试服务器: %v", err)
}
server := &http.Server{ReadHeaderTimeout: time.Second}
defer server.Close()
go func() {
err := server.Serve(listener)
if err != nil && err != http.ErrServerClosed && !errors.Is(err, net.ErrClosed) {
t.Errorf("serve failed: %v", err)
}
}()
time.Sleep(100 * time.Millisecond)
listener.Close()
time.Sleep(100 * time.Millisecond)
err = checkPortAvailable(port)
if err != nil {
t.Fatalf("端口关闭后应该可用: %v", err)
}
t.Log("端口关闭后可用测试通过")
}
func TestCheckPortAvailableErrorContainsPort(t *testing.T) {
port := 19829
listener, err := net.Listen("tcp", ":19829") //nolint:gosec
if err != nil {
t.Fatalf("无法启动测试服务器: %v", err)
}
defer listener.Close()
time.Sleep(100 * time.Millisecond)
err = checkPortAvailable(port)
if err == nil {
t.Fatal("端口被占用时应该返回错误")
}
if !strings.Contains(err.Error(), "19829") {
t.Fatalf("错误信息应包含端口号 19829实际: %v", err)
}
t.Log("端口错误信息包含端口号测试通过")
}
func TestGetDesktopConfigPath(t *testing.T) {
path := getDesktopConfigPath()
if path == "" {
t.Fatal("getDesktopConfigPath 应返回非空路径")
}
if !strings.Contains(path, "config.yaml") {
t.Fatalf("路径应包含 config.yaml实际: %s", path)
}
t.Log("getDesktopConfigPath 测试通过")
}
func TestDesktopConfiguredPortHelpers(t *testing.T) {
port := 19830
if got := desktopListenAddr(port); got != ":19830" {
t.Fatalf("HTTP 监听地址应使用配置端口,实际: %s", got)
}
if got := desktopURL(port); got != "http://localhost:19830" {
t.Fatalf("浏览器 URL 应使用配置端口,实际: %s", got)
}
if got := desktopPortMenuTitle(port); got != "端口: 19830" {
t.Fatalf("托盘端口显示应使用配置端口,实际: %s", got)
}
}
func TestDesktopConfigErrorMessageContainsPathAndReason(t *testing.T) {
msg := desktopConfigErrorMessage("/tmp/nex/config.yaml", errors.New("yaml parse failed"))
if !strings.Contains(msg, "/tmp/nex/config.yaml") {
t.Fatalf("配置错误提示应包含配置路径,实际: %s", msg)
}
if !strings.Contains(msg, "yaml parse failed") {
t.Fatalf("配置错误提示应包含失败原因,实际: %s", msg)
}
}