feat: 增强桌面启动失败提示与测试覆盖
This commit is contained in:
140
backend/cmd/desktop/reporter_test.go
Normal file
140
backend/cmd/desktop/reporter_test.go
Normal file
@@ -0,0 +1,140 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zaptest/observer"
|
||||
)
|
||||
|
||||
type commandCall struct {
|
||||
timeout time.Duration
|
||||
env []string
|
||||
name string
|
||||
args []string
|
||||
}
|
||||
|
||||
type fakeCommandRunner struct {
|
||||
paths map[string]bool
|
||||
runErrs map[string]error
|
||||
calls []commandCall
|
||||
}
|
||||
|
||||
func (r *fakeCommandRunner) LookPath(file string) (string, error) {
|
||||
if r.paths[file] {
|
||||
return "/usr/bin/" + file, nil
|
||||
}
|
||||
return "", exec.ErrNotFound
|
||||
}
|
||||
|
||||
func (r *fakeCommandRunner) Run(timeout time.Duration, env []string, name string, args ...string) error {
|
||||
r.calls = append(r.calls, commandCall{
|
||||
timeout: timeout,
|
||||
env: append([]string(nil), env...),
|
||||
name: name,
|
||||
args: append([]string(nil), args...),
|
||||
})
|
||||
if err := r.runErrs[name]; err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestRunPromptPipelineFallbackOrder(t *testing.T) {
|
||||
var calls []string
|
||||
channels := []promptChannel{
|
||||
{
|
||||
name: "unavailable",
|
||||
available: func() error {
|
||||
calls = append(calls, "available-1")
|
||||
return errors.New("missing")
|
||||
},
|
||||
run: func(promptRequest) error {
|
||||
calls = append(calls, "run-1")
|
||||
return nil
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "failed",
|
||||
available: func() error {
|
||||
calls = append(calls, "available-2")
|
||||
return nil
|
||||
},
|
||||
run: func(promptRequest) error {
|
||||
calls = append(calls, "run-2")
|
||||
return errors.New("failed")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "success",
|
||||
available: func() error {
|
||||
calls = append(calls, "available-3")
|
||||
return nil
|
||||
},
|
||||
run: func(promptRequest) error {
|
||||
calls = append(calls, "run-3")
|
||||
return nil
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var fallback bytes.Buffer
|
||||
runPromptPipeline(promptRequest{title: "Nex 启动失败", message: "启动失败"}, channels, &fallback, zap.NewNop())
|
||||
|
||||
want := []string{"available-1", "available-2", "run-2", "available-3", "run-3"}
|
||||
if fmt.Sprint(calls) != fmt.Sprint(want) {
|
||||
t.Fatalf("调用顺序 = %v, want %v", calls, want)
|
||||
}
|
||||
if fallback.Len() != 0 {
|
||||
t.Fatalf("成功通道后不应写入 fallback,实际: %s", fallback.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunPromptPipelineWritesFallback(t *testing.T) {
|
||||
channels := []promptChannel{
|
||||
{
|
||||
name: "unavailable",
|
||||
available: func() error { return errors.New("missing") },
|
||||
run: func(promptRequest) error { return nil },
|
||||
},
|
||||
}
|
||||
|
||||
var fallback bytes.Buffer
|
||||
runPromptPipeline(promptRequest{title: "Nex 启动失败", message: "端口被占用"}, channels, &fallback, zap.NewNop())
|
||||
|
||||
want := "错误: Nex 启动失败: 端口被占用\n"
|
||||
if fallback.String() != want {
|
||||
t.Fatalf("fallback = %q, want %q", fallback.String(), want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReportStartupFailureLogsRedactedError(t *testing.T) {
|
||||
old := buildPromptChannels
|
||||
buildPromptChannels = func(commandRunner) []promptChannel {
|
||||
return []promptChannel{{name: "fake-success", run: func(promptRequest) error { return nil }}}
|
||||
}
|
||||
t.Cleanup(func() { buildPromptChannels = old })
|
||||
|
||||
core, logs := observer.New(zap.ErrorLevel)
|
||||
logger := zap.New(core)
|
||||
err := errors.New("数据库连接失败: nex:secret@tcp(localhost:3306)/nex password=secret api_key=sk-test")
|
||||
|
||||
reportStartupFailure(err, logger)
|
||||
|
||||
entries := logs.All()
|
||||
if len(entries) != 1 {
|
||||
t.Fatalf("应记录 1 条错误日志,实际: %d", len(entries))
|
||||
}
|
||||
fields := fmt.Sprint(entries[0].ContextMap())
|
||||
for _, secret := range []string{"secret", "sk-test"} {
|
||||
if strings.Contains(fields, secret) {
|
||||
t.Fatalf("启动失败日志不应包含敏感信息 %q,实际: %s", secret, fields)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user