update: chunk upload
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user