ec9431bfa4
多机/容器化第一时间断裂的隐患(ARCHITECTURE_REVIEW §7 #1):此前报告 源(reportStore)与 .docx 产物(reportExport/reportRender)都写 mcp-go 本地 SUNDYNIX_REPORTS_DIR,gateway 再按同一路径 c.File 回流——mcp-go 与 gateway 不共享磁盘即断。 - blob 包从 gateway/internal 提到 sundynix-shared/blob,gateway 与 mcp-go 共用同一 MinIO;新增 PutBytes/GetBytes 走二进制(.docx)。 - mcp-go 注入 blob:report 源/产物优先 Put 到对象存储(键 reports/<id>.{json,docx}), 导出结果返回 minio://<key>;MinIO 未就绪回退本地盘(单机降级,getSource 兼容旧本地报告)。 - gateway ExportReport 识别 minio:// → GetBytes 流式下载,否则 c.File 本地降级。 - 测试:mcp 本地回落往返单测 + shared/blob 真 MinIO 二进制往返(BLOB_TEST_ENDPOINT 门控)。 四模块 build 绿,受影响测试全过。 - 附带:go mod tidy 引入 genproto 拆包冲突,四模块统一钉单体 genproto 新版解决 (注:勿 go work sync,会剪掉 indirect require 回落旧版重现冲突)。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
58 lines
1.8 KiB
Go
58 lines
1.8 KiB
Go
package mcp
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"os"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/sundynix/sundynix-shared/blob"
|
|
"github.com/sundynix/sundynix-shared/contract"
|
|
|
|
"github.com/sundynix/sundynix-mcp-go/internal/office"
|
|
)
|
|
|
|
// blob 未就绪(MinIO 连不上)时,报告源/产物回落本地盘:
|
|
// putSource → getSource 往返一致,putDocx 返回本地路径(非 minio:// 标记)。
|
|
// 这是单机/无对象存储的降级路径,必须始终可用。
|
|
func TestReport_LocalFallback_WhenBlobNotReady(t *testing.T) {
|
|
// 隔离到临时目录,避免污染系统 temp 下的 sundynix-reports。
|
|
dir := t.TempDir()
|
|
t.Setenv("SUNDYNIX_REPORTS_DIR", dir)
|
|
|
|
g := &Gateway{blob: &blob.Store{}} // cli=nil → Ready()=false
|
|
if g.blob.Ready() {
|
|
t.Fatal("裸 blob.Store 应为未就绪")
|
|
}
|
|
ctx := context.Background()
|
|
id := "report_local_fallback"
|
|
|
|
// 存源 → 取源往返。
|
|
src := reportSource{Title: "标题", Sections: []office.Section{{Heading: "H", Body: "B"}}}
|
|
data, _ := json.Marshal(src)
|
|
if err := g.putSource(ctx, id, data); err != nil {
|
|
t.Fatalf("putSource: %v", err)
|
|
}
|
|
got, err := g.getSource(ctx, id)
|
|
if err != nil {
|
|
t.Fatalf("getSource: %v", err)
|
|
}
|
|
var back reportSource
|
|
if err := json.Unmarshal(got, &back); err != nil || back.Title != "标题" {
|
|
t.Fatalf("源往返不一致: %v / %+v", err, back)
|
|
}
|
|
|
|
// 产物回落本地路径:返回真实路径、无 minio:// 前缀、文件存在。
|
|
ref, err := g.putDocx(ctx, id, []byte("PK\x03\x04fake-docx"))
|
|
if err != nil {
|
|
t.Fatalf("putDocx: %v", err)
|
|
}
|
|
if strings.HasPrefix(ref, contract.BlobScheme) {
|
|
t.Errorf("blob 未就绪不应返回 minio:// 标记,得 %q", ref)
|
|
}
|
|
if _, serr := os.Stat(ref); serr != nil {
|
|
t.Errorf("本地产物应落盘,stat %s: %v", ref, serr)
|
|
}
|
|
}
|