spark-server/internal/infrastructure/objectstore/store_test.go
zhr ae9a71034d feat: implement Spark IM V3 modular monolith
Add HTTP /v1 MVC, TCP send path, groups with server-side member-avatar collage, object-storage upload, and friends/favorites around the architecture-v3 layout.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 19:52:11 +08:00

105 lines
2.6 KiB
Go

package objectstore
import (
"errors"
"os"
"strings"
"testing"
"time"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/s3"
"github.com/aws/aws-sdk-go-v2/service/s3/types"
"go.uber.org/zap"
"spark-server/internal/pkg/errs"
)
func TestParseEndpoint(t *testing.T) {
host, secure, err := parseEndpoint("http://47.236.66.9:9000", true)
if err != nil || host != "47.236.66.9:9000" || secure {
t.Fatalf("%s %v %v", host, secure, err)
}
host, secure, err = parseEndpoint("47.236.66.9:9000", false)
if err != nil || host != "47.236.66.9:9000" || secure {
t.Fatalf("plain %s %v %v", host, secure, err)
}
host, secure, err = parseEndpoint("https://fs.example.com", false)
if err != nil || host != "fs.example.com" || !secure {
t.Fatalf("https %s %v %v", host, secure, err)
}
}
func TestOpenEmpty(t *testing.T) {
s, err := Open(&Options{})
if err != nil || s.Ready() {
t.Fatalf("ready=%v err=%v", s.Ready(), err)
}
}
func TestPresignLocal(t *testing.T) {
client := newS3Client(defaultRegion, "http://127.0.0.1:9000", "ak", "sk")
s := &Store{client: client, presign: s3.NewPresignClient(client), bucket: "spark"}
u, err := s.PresignPut(t.Context(), "chat/a.jpg", "image/jpeg", time.Hour)
if err != nil {
t.Fatal(err)
}
if !strings.Contains(u, "127.0.0.1:9000/spark/chat/a.jpg") {
t.Fatalf("%s", u)
}
g, err := s.PresignGet(t.Context(), "perm/avatar/1.jpg", time.Minute)
if err != nil {
t.Fatal(err)
}
if !strings.Contains(g, "perm/avatar/1.jpg") {
t.Fatalf("%s", g)
}
}
func TestGetPutNotReady(t *testing.T) {
s, err := Open(&Options{})
if err != nil {
t.Fatal(err)
}
if _, err := s.Get(t.Context(), "perm/a"); !errors.Is(err, errs.ErrAvailable) {
t.Fatalf("get %v", err)
}
if err := s.Put(t.Context(), "perm/a", []byte("x"), "image/jpeg"); !errors.Is(err, errs.ErrAvailable) {
t.Fatalf("put %v", err)
}
}
func TestMapObjectErr(t *testing.T) {
err := mapObjectErr(&types.NoSuchKey{Message: aws.String("gone")})
if !errors.Is(err, errs.ErrMediaExpired) {
t.Fatalf("%v", err)
}
err = mapObjectErr(errors.New("boom"))
if !errors.Is(err, errs.ErrOperatFail) {
t.Fatalf("%v", err)
}
}
func TestOpenLive(t *testing.T) {
if os.Getenv("SPARK_S3_LIVE") == "" {
t.Skip("set SPARK_S3_LIVE=1 to hit RustFS")
}
s, err := Open(&Options{
Endpoint: "47.236.66.9:9000",
AccessKey: os.Getenv("SPARK_S3_ACCESS_KEY"),
SecretKey: os.Getenv("SPARK_S3_SECRET_KEY"),
Bucket: "spark",
ChatExpireDays: 365,
Log: zap.NewNop(),
})
if err != nil {
t.Fatal(err)
}
if !s.Ready() {
t.Fatal("not ready")
}
if err := s.Ping(t.Context()); err != nil {
t.Fatal(err)
}
}