85 lines
2.6 KiB
Go
85 lines
2.6 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"mime/multipart"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strconv"
|
|
"testing"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
// 分片数学: 片数 ceil 与每片期望大小
|
|
func TestChunkMath(t *testing.T) {
|
|
if got := expectedChunks(5<<30 + 1); got != 6 {
|
|
t.Fatalf("expectedChunks(5GB+1) = %d, want 6", got)
|
|
}
|
|
if got := expectedChunks(5 << 30); got != 5 {
|
|
t.Fatalf("expectedChunks(5GB) = %d, want 5", got)
|
|
}
|
|
if got := expectedChunkSize(5<<30+1, 0); got != chunkSize {
|
|
t.Fatalf("chunk0 size = %d, want 1GB", got)
|
|
}
|
|
if got := expectedChunkSize(5<<30+1, 5); got != 1 {
|
|
t.Fatalf("last chunk size = %d, want 1", got)
|
|
}
|
|
}
|
|
|
|
func chunkRequest(t *testing.T, uploadID string, idx, totalChunks int, filename string, totalSize int64, content []byte) *gin.Context {
|
|
t.Helper()
|
|
var buf bytes.Buffer
|
|
w := multipart.NewWriter(&buf)
|
|
fw, err := w.CreateFormFile("chunk", "chunk")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
fw.Write(content)
|
|
w.Close()
|
|
req := httptest.NewRequest("POST", "/upload-chunk", &buf)
|
|
req.Header.Set("Content-Type", w.FormDataContentType())
|
|
req.Header.Set("X-Upload-Id", uploadID)
|
|
req.Header.Set("X-Chunk-Index", strconv.Itoa(idx))
|
|
req.Header.Set("X-Total-Chunks", strconv.Itoa(totalChunks))
|
|
req.Header.Set("X-Filename", filename)
|
|
req.Header.Set("X-Total-Size", strconv.FormatInt(totalSize, 10))
|
|
rec := httptest.NewRecorder()
|
|
c, _ := gin.CreateTestContext(rec)
|
|
c.Request = req
|
|
return c
|
|
}
|
|
|
|
// 校验拒绝路径: 非法 id / 小于阈值 / 越界 / 片数不匹配 / 超配额, 均不落盘
|
|
func TestChunkHandlerRejections(t *testing.T) {
|
|
*auditDir = "" // 测试不写审计日志
|
|
oldQuota := *quota
|
|
*quota = 1 << 30
|
|
defer func() { *quota = oldQuota }()
|
|
|
|
cases := []struct {
|
|
name string
|
|
id string
|
|
idx int
|
|
total int
|
|
fn string
|
|
size int64
|
|
status int
|
|
}{
|
|
{"invalid upload id", "bad id!", 0, 6, "x.bin", chunkThreshold + 1, http.StatusBadRequest},
|
|
{"below threshold", "uploadid123456", 0, 1, "x.bin", chunkThreshold, http.StatusBadRequest},
|
|
{"index out of range", "uploadid123456", 6, 6, "x.bin", chunkThreshold + 1, http.StatusBadRequest},
|
|
{"chunk count mismatch", "uploadid123456", 0, 2, "x.bin", chunkThreshold + 1, http.StatusBadRequest},
|
|
{"quota exceeded", "uploadid123456", 0, 6, "x.bin", chunkThreshold + 1, http.StatusInsufficientStorage},
|
|
}
|
|
for _, tc := range cases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
c := chunkRequest(t, tc.id, tc.idx, tc.total, tc.fn, tc.size, []byte("data"))
|
|
uploadChunkHandler(c)
|
|
if c.Writer.Status() != tc.status {
|
|
t.Fatalf("status = %d, want %d", c.Writer.Status(), tc.status)
|
|
}
|
|
})
|
|
}
|
|
}
|