fix: add local static file storage fallback
This commit is contained in:
@@ -1,10 +1,15 @@
|
||||
package runner
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/easyai/easyai-ai-gateway/apps/api/internal/config"
|
||||
"github.com/easyai/easyai-ai-gateway/apps/api/internal/store"
|
||||
)
|
||||
|
||||
@@ -109,17 +114,20 @@ func TestGeneratedAssetDecisionUploadsURLWhenPolicyUploadAll(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGeneratedAssetDecisionSkipsAllWhenPolicyUploadNone(t *testing.T) {
|
||||
func TestGeneratedAssetDecisionStoresInlineLocallyWhenPolicyUploadNone(t *testing.T) {
|
||||
item := map[string]any{
|
||||
"b64_json": base64.StdEncoding.EncodeToString([]byte("inline image")),
|
||||
}
|
||||
|
||||
decision, err := generatedAssetDecisionForItem("images.generations", item, generatedAssetUploadPolicy{UploadInlineMedia: false, UploadURLMedia: false})
|
||||
decision, err := generatedAssetDecisionForItem("images.generations", item, generatedAssetUploadPolicyFromName(store.FileStorageResultUploadPolicyUploadNone))
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if decision.Inline != nil || decision.URL != nil || len(decision.StripKeys) != 0 {
|
||||
t.Fatalf("upload_none should keep the result unchanged: %+v", decision)
|
||||
if decision.Inline == nil || decision.URL != nil {
|
||||
t.Fatalf("upload_none should still turn inline payloads into static URLs: %+v", decision)
|
||||
}
|
||||
if !containsString(decision.StripKeys, "b64_json") {
|
||||
t.Fatalf("inline payload should be stripped before persistence: %+v", decision.StripKeys)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,17 +140,17 @@ func TestGeneratedAssetUploadPolicyFromName(t *testing.T) {
|
||||
{
|
||||
name: "default",
|
||||
policyName: store.FileStorageResultUploadPolicyDefault,
|
||||
want: generatedAssetUploadPolicy{UploadInlineMedia: true, UploadURLMedia: false},
|
||||
want: generatedAssetUploadPolicy{UploadInlineMedia: true, UploadURLMedia: false, StoreInlineMediaLocally: false},
|
||||
},
|
||||
{
|
||||
name: "upload all",
|
||||
policyName: store.FileStorageResultUploadPolicyUploadAll,
|
||||
want: generatedAssetUploadPolicy{UploadInlineMedia: true, UploadURLMedia: true},
|
||||
want: generatedAssetUploadPolicy{UploadInlineMedia: true, UploadURLMedia: true, StoreInlineMediaLocally: false},
|
||||
},
|
||||
{
|
||||
name: "upload none",
|
||||
policyName: store.FileStorageResultUploadPolicyUploadNone,
|
||||
want: generatedAssetUploadPolicy{UploadInlineMedia: false, UploadURLMedia: false},
|
||||
want: generatedAssetUploadPolicy{UploadInlineMedia: true, UploadURLMedia: false, StoreInlineMediaLocally: true},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -185,3 +193,87 @@ func TestGeneratedAssetFileNameIsUniqueAndTyped(t *testing.T) {
|
||||
t.Fatalf("unexpected generated file name: %s", first)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUploadGeneratedAssetStoresLocalWhenNoChannels(t *testing.T) {
|
||||
storageDir := t.TempDir()
|
||||
service := &Service{cfg: config.Config{LocalGeneratedStorageDir: storageDir}}
|
||||
payload := []byte{0x89, 'P', 'N', 'G', 0x0d, 0x0a, 0x1a, 0x0a, 0, 0, 0, 0}
|
||||
asset := &generatedInlineAsset{
|
||||
Bytes: payload,
|
||||
ContentType: "image/jpeg",
|
||||
Kind: "image",
|
||||
SourceKey: "b64_json",
|
||||
}
|
||||
|
||||
upload, contentType, kind, strategy, err := service.uploadGeneratedAsset(context.Background(), "task-123", asset, 0, nil, false)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if contentType != "image/png" || kind != "image" || strategy != "local_static_inline_media" {
|
||||
t.Fatalf("unexpected local upload metadata: contentType=%s kind=%s strategy=%s", contentType, kind, strategy)
|
||||
}
|
||||
urlValue := stringFromAny(upload["url"])
|
||||
if !strings.HasPrefix(urlValue, "/static/generated/gateway-result-task-123-01-") || !strings.HasSuffix(urlValue, ".png") {
|
||||
t.Fatalf("unexpected local static URL: %s", urlValue)
|
||||
}
|
||||
entries, err := os.ReadDir(storageDir)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to read local static dir: %v", err)
|
||||
}
|
||||
if len(entries) != 1 || !strings.HasSuffix(entries[0].Name(), ".png") {
|
||||
t.Fatalf("expected one PNG file in local static dir, got %+v", entries)
|
||||
}
|
||||
stored, err := os.ReadFile(filepath.Join(storageDir, entries[0].Name()))
|
||||
if err != nil {
|
||||
t.Fatalf("failed to read local static file: %v", err)
|
||||
}
|
||||
if !bytes.Equal(stored, payload) {
|
||||
t.Fatalf("stored payload does not match source payload")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUploadFileStoresLocalWhenNoChannels(t *testing.T) {
|
||||
storageDir := t.TempDir()
|
||||
service := &Service{cfg: config.Config{
|
||||
LocalUploadedStorageDir: storageDir,
|
||||
ServerMainBaseURL: "http://127.0.0.1:1",
|
||||
ServerMainInternalToken: "change-me",
|
||||
}}
|
||||
payload := []byte("%PDF-1.4")
|
||||
|
||||
upload, err := service.UploadFile(context.Background(), FileUploadPayload{
|
||||
Bytes: payload,
|
||||
ContentType: "application/pdf",
|
||||
FileName: "用户文件.png",
|
||||
Source: "playground",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
urlValue := stringFromAny(upload["url"])
|
||||
if !strings.HasPrefix(urlValue, "/static/uploaded/") || !strings.HasSuffix(urlValue, ".pdf") {
|
||||
t.Fatalf("unexpected uploaded local static URL: %s", urlValue)
|
||||
}
|
||||
storageChannel, _ := upload["storageChannel"].(map[string]any)
|
||||
if stringFromAny(storageChannel["provider"]) != "local_static" {
|
||||
t.Fatalf("expected local static provider metadata, got %+v", upload["storageChannel"])
|
||||
}
|
||||
assetStorage, _ := upload["assetStorage"].(map[string]any)
|
||||
if stringFromAny(assetStorage["strategy"]) != "local_static_upload" || stringFromAny(assetStorage["scene"]) != store.FileStorageSceneUpload {
|
||||
t.Fatalf("unexpected upload asset storage metadata: %+v", assetStorage)
|
||||
}
|
||||
entries, err := os.ReadDir(storageDir)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to read uploaded static dir: %v", err)
|
||||
}
|
||||
if len(entries) != 1 || !strings.HasSuffix(entries[0].Name(), ".pdf") {
|
||||
t.Fatalf("expected one PDF file in uploaded static dir, got %+v", entries)
|
||||
}
|
||||
stored, err := os.ReadFile(filepath.Join(storageDir, entries[0].Name()))
|
||||
if err != nil {
|
||||
t.Fatalf("failed to read uploaded static file: %v", err)
|
||||
}
|
||||
if !bytes.Equal(stored, payload) {
|
||||
t.Fatalf("stored uploaded payload does not match source payload")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user