parent
31315c86ee
commit
c6130ab078
@ -0,0 +1,22 @@
|
||||
package backoff
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestConstantBackoff_Next(t *testing.T) {
|
||||
a := assert.New(t)
|
||||
|
||||
b := &ConstantBackoff{Sleep: time.Duration(0), Max: 3}
|
||||
a.True(b.Next())
|
||||
a.True(b.Next())
|
||||
a.True(b.Next())
|
||||
a.False(b.Next())
|
||||
b.Reset()
|
||||
a.True(b.Next())
|
||||
a.True(b.Next())
|
||||
a.True(b.Next())
|
||||
a.False(b.Next())
|
||||
}
|
@ -0,0 +1,250 @@
|
||||
package chunk
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/cloudreve/Cloudreve/v3/pkg/filesystem/chunk/backoff"
|
||||
"github.com/cloudreve/Cloudreve/v3/pkg/filesystem/fsctx"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNewChunkGroup(t *testing.T) {
|
||||
a := assert.New(t)
|
||||
|
||||
testCases := []struct {
|
||||
fileSize uint64
|
||||
chunkSize uint64
|
||||
expectedInnerChunkSize uint64
|
||||
expectedChunkNum uint64
|
||||
expectedInfo [][2]int //Start, Index,Length
|
||||
}{
|
||||
{10, 0, 10, 1, [][2]int{{0, 10}}},
|
||||
{0, 0, 0, 1, [][2]int{{0, 0}}},
|
||||
{0, 10, 10, 1, [][2]int{{0, 0}}},
|
||||
{50, 10, 10, 5, [][2]int{
|
||||
{0, 10},
|
||||
{10, 10},
|
||||
{20, 10},
|
||||
{30, 10},
|
||||
{40, 10},
|
||||
}},
|
||||
{50, 50, 50, 1, [][2]int{
|
||||
{0, 50},
|
||||
}},
|
||||
|
||||
{50, 15, 15, 4, [][2]int{
|
||||
{0, 15},
|
||||
{15, 15},
|
||||
{30, 15},
|
||||
{45, 5},
|
||||
}},
|
||||
}
|
||||
|
||||
for index, testCase := range testCases {
|
||||
file := &fsctx.FileStream{Size: testCase.fileSize}
|
||||
chunkGroup := NewChunkGroup(file, testCase.chunkSize, &backoff.ConstantBackoff{}, true)
|
||||
a.EqualValues(testCase.expectedChunkNum, chunkGroup.Num(),
|
||||
"TestCase:%d,ChunkNum()", index)
|
||||
a.EqualValues(testCase.expectedInnerChunkSize, chunkGroup.chunkSize,
|
||||
"TestCase:%d,InnerChunkSize()", index)
|
||||
a.EqualValues(testCase.expectedChunkNum, chunkGroup.Num(),
|
||||
"TestCase:%d,len(Chunks)", index)
|
||||
a.EqualValues(testCase.fileSize, chunkGroup.Total())
|
||||
|
||||
for cIndex, info := range testCase.expectedInfo {
|
||||
a.True(chunkGroup.Next())
|
||||
a.EqualValues(info[1], chunkGroup.Length(),
|
||||
"TestCase:%d,Chunks[%d].Length()", index, cIndex)
|
||||
a.EqualValues(info[0], chunkGroup.Start(),
|
||||
"TestCase:%d,Chunks[%d].Start()", index, cIndex)
|
||||
|
||||
a.Equal(cIndex == len(testCase.expectedInfo)-1, chunkGroup.IsLast(),
|
||||
"TestCase:%d,Chunks[%d].IsLast()", index, cIndex)
|
||||
|
||||
a.NotEmpty(chunkGroup.RangeHeader())
|
||||
}
|
||||
a.False(chunkGroup.Next())
|
||||
}
|
||||
}
|
||||
|
||||
func TestChunkGroup_TempAvailablet(t *testing.T) {
|
||||
a := assert.New(t)
|
||||
|
||||
file := &fsctx.FileStream{Size: 1}
|
||||
c := NewChunkGroup(file, 0, &backoff.ConstantBackoff{}, true)
|
||||
a.False(c.TempAvailable())
|
||||
|
||||
f, err := os.CreateTemp("", "TestChunkGroup_TempAvailablet.*")
|
||||
defer func() {
|
||||
f.Close()
|
||||
os.Remove(f.Name())
|
||||
}()
|
||||
a.NoError(err)
|
||||
c.bufferTemp = f
|
||||
|
||||
a.False(c.TempAvailable())
|
||||
f.Write([]byte("1"))
|
||||
a.True(c.TempAvailable())
|
||||
|
||||
}
|
||||
|
||||
func TestChunkGroup_Process(t *testing.T) {
|
||||
a := assert.New(t)
|
||||
file := &fsctx.FileStream{Size: 10}
|
||||
|
||||
// success
|
||||
{
|
||||
file.File = io.NopCloser(strings.NewReader("1234567890"))
|
||||
c := NewChunkGroup(file, 5, &backoff.ConstantBackoff{}, true)
|
||||
count := 0
|
||||
a.True(c.Next())
|
||||
a.NoError(c.Process(func(c *ChunkGroup, chunk io.Reader) error {
|
||||
count++
|
||||
res, err := io.ReadAll(chunk)
|
||||
a.NoError(err)
|
||||
a.EqualValues("12345", string(res))
|
||||
return nil
|
||||
}))
|
||||
a.True(c.Next())
|
||||
a.NoError(c.Process(func(c *ChunkGroup, chunk io.Reader) error {
|
||||
count++
|
||||
res, err := io.ReadAll(chunk)
|
||||
a.NoError(err)
|
||||
a.EqualValues("67890", string(res))
|
||||
return nil
|
||||
}))
|
||||
a.False(c.Next())
|
||||
a.Equal(2, count)
|
||||
}
|
||||
|
||||
// retry, read from buffer file
|
||||
{
|
||||
file.File = io.NopCloser(strings.NewReader("1234567890"))
|
||||
c := NewChunkGroup(file, 5, &backoff.ConstantBackoff{Max: 2}, true)
|
||||
count := 0
|
||||
a.True(c.Next())
|
||||
a.NoError(c.Process(func(c *ChunkGroup, chunk io.Reader) error {
|
||||
count++
|
||||
res, err := io.ReadAll(chunk)
|
||||
a.NoError(err)
|
||||
a.EqualValues("12345", string(res))
|
||||
return nil
|
||||
}))
|
||||
a.True(c.Next())
|
||||
a.NoError(c.Process(func(c *ChunkGroup, chunk io.Reader) error {
|
||||
count++
|
||||
res, err := io.ReadAll(chunk)
|
||||
a.NoError(err)
|
||||
a.EqualValues("67890", string(res))
|
||||
if count == 2 {
|
||||
return errors.New("error")
|
||||
}
|
||||
return nil
|
||||
}))
|
||||
a.False(c.Next())
|
||||
a.Equal(3, count)
|
||||
}
|
||||
|
||||
// retry, read from seeker
|
||||
{
|
||||
f, _ := os.CreateTemp("", "TestChunkGroup_Process.*")
|
||||
f.Write([]byte("1234567890"))
|
||||
f.Seek(0, 0)
|
||||
defer func() {
|
||||
f.Close()
|
||||
os.Remove(f.Name())
|
||||
}()
|
||||
file.File = f
|
||||
file.Seeker = f
|
||||
c := NewChunkGroup(file, 5, &backoff.ConstantBackoff{Max: 2}, false)
|
||||
count := 0
|
||||
a.True(c.Next())
|
||||
a.NoError(c.Process(func(c *ChunkGroup, chunk io.Reader) error {
|
||||
count++
|
||||
res, err := io.ReadAll(chunk)
|
||||
a.NoError(err)
|
||||
a.EqualValues("12345", string(res))
|
||||
return nil
|
||||
}))
|
||||
a.True(c.Next())
|
||||
a.NoError(c.Process(func(c *ChunkGroup, chunk io.Reader) error {
|
||||
count++
|
||||
res, err := io.ReadAll(chunk)
|
||||
a.NoError(err)
|
||||
a.EqualValues("67890", string(res))
|
||||
if count == 2 {
|
||||
return errors.New("error")
|
||||
}
|
||||
return nil
|
||||
}))
|
||||
a.False(c.Next())
|
||||
a.Equal(3, count)
|
||||
}
|
||||
|
||||
// retry, seek error
|
||||
{
|
||||
f, _ := os.CreateTemp("", "TestChunkGroup_Process.*")
|
||||
f.Write([]byte("1234567890"))
|
||||
f.Seek(0, 0)
|
||||
defer func() {
|
||||
f.Close()
|
||||
os.Remove(f.Name())
|
||||
}()
|
||||
file.File = f
|
||||
file.Seeker = f
|
||||
c := NewChunkGroup(file, 5, &backoff.ConstantBackoff{Max: 2}, false)
|
||||
count := 0
|
||||
a.True(c.Next())
|
||||
a.NoError(c.Process(func(c *ChunkGroup, chunk io.Reader) error {
|
||||
count++
|
||||
res, err := io.ReadAll(chunk)
|
||||
a.NoError(err)
|
||||
a.EqualValues("12345", string(res))
|
||||
return nil
|
||||
}))
|
||||
a.True(c.Next())
|
||||
f.Close()
|
||||
a.Error(c.Process(func(c *ChunkGroup, chunk io.Reader) error {
|
||||
count++
|
||||
if count == 2 {
|
||||
return errors.New("error")
|
||||
}
|
||||
return nil
|
||||
}))
|
||||
a.False(c.Next())
|
||||
a.Equal(2, count)
|
||||
}
|
||||
|
||||
// retry, finally error
|
||||
{
|
||||
f, _ := os.CreateTemp("", "TestChunkGroup_Process.*")
|
||||
f.Write([]byte("1234567890"))
|
||||
f.Seek(0, 0)
|
||||
defer func() {
|
||||
f.Close()
|
||||
os.Remove(f.Name())
|
||||
}()
|
||||
file.File = f
|
||||
file.Seeker = f
|
||||
c := NewChunkGroup(file, 5, &backoff.ConstantBackoff{Max: 2}, false)
|
||||
count := 0
|
||||
a.True(c.Next())
|
||||
a.NoError(c.Process(func(c *ChunkGroup, chunk io.Reader) error {
|
||||
count++
|
||||
res, err := io.ReadAll(chunk)
|
||||
a.NoError(err)
|
||||
a.EqualValues("12345", string(res))
|
||||
return nil
|
||||
}))
|
||||
a.True(c.Next())
|
||||
a.Error(c.Process(func(c *ChunkGroup, chunk io.Reader) error {
|
||||
count++
|
||||
return errors.New("error")
|
||||
}))
|
||||
a.False(c.Next())
|
||||
a.Equal(1, count)
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
package onedrive
|
||||
|
||||
import (
|
||||
model "github.com/cloudreve/Cloudreve/v3/models"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDriver_replaceSourceHost(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
origin string
|
||||
cdn string
|
||||
want string
|
||||
wantErr bool
|
||||
}{
|
||||
{"TestNoReplace", "http://1dr.ms/download.aspx?123456", "", "http://1dr.ms/download.aspx?123456", false},
|
||||
{"TestReplaceCorrect", "http://1dr.ms/download.aspx?123456", "https://test.com:8080", "https://test.com:8080/download.aspx?123456", false},
|
||||
{"TestCdnFormatError", "http://1dr.ms/download.aspx?123456", string([]byte{0x7f}), "", true},
|
||||
{"TestSrcFormatError", string([]byte{0x7f}), "https://test.com:8080", "", true},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
policy := &model.Policy{}
|
||||
policy.OptionsSerialized.OdProxy = tt.cdn
|
||||
handler := Driver{
|
||||
Policy: policy,
|
||||
}
|
||||
got, err := handler.replaceSourceHost(tt.origin)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("replaceSourceHost() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if got != tt.want {
|
||||
t.Errorf("replaceSourceHost() got = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in new issue