github.com/cloudreve/Cloudreve/v3@v3.0.0-20240224133659-3edb00a6484c/pkg/filesystem/driver/local/handler_test.go (about) 1 package local 2 3 import ( 4 "context" 5 model "github.com/cloudreve/Cloudreve/v3/models" 6 "github.com/cloudreve/Cloudreve/v3/pkg/auth" 7 "github.com/cloudreve/Cloudreve/v3/pkg/filesystem/driver" 8 "github.com/cloudreve/Cloudreve/v3/pkg/filesystem/fsctx" 9 "github.com/cloudreve/Cloudreve/v3/pkg/serializer" 10 "github.com/cloudreve/Cloudreve/v3/pkg/util" 11 "github.com/jinzhu/gorm" 12 "github.com/stretchr/testify/assert" 13 "io" 14 "os" 15 "strings" 16 "testing" 17 ) 18 19 func TestHandler_Put(t *testing.T) { 20 asserts := assert.New(t) 21 handler := Driver{} 22 23 defer func() { 24 os.Remove(util.RelativePath("TestHandler_Put.txt")) 25 os.Remove(util.RelativePath("inner/TestHandler_Put.txt")) 26 }() 27 28 testCases := []struct { 29 file fsctx.FileHeader 30 errContains string 31 }{ 32 {&fsctx.FileStream{ 33 SavePath: "TestHandler_Put.txt", 34 File: io.NopCloser(strings.NewReader("")), 35 }, ""}, 36 {&fsctx.FileStream{ 37 SavePath: "TestHandler_Put.txt", 38 File: io.NopCloser(strings.NewReader("")), 39 }, "file with the same name existed or unavailable"}, 40 {&fsctx.FileStream{ 41 SavePath: "inner/TestHandler_Put.txt", 42 File: io.NopCloser(strings.NewReader("")), 43 }, ""}, 44 {&fsctx.FileStream{ 45 Mode: fsctx.Append | fsctx.Overwrite, 46 SavePath: "inner/TestHandler_Put.txt", 47 File: io.NopCloser(strings.NewReader("123")), 48 }, ""}, 49 {&fsctx.FileStream{ 50 AppendStart: 10, 51 Mode: fsctx.Append | fsctx.Overwrite, 52 SavePath: "inner/TestHandler_Put.txt", 53 File: io.NopCloser(strings.NewReader("123")), 54 }, "size of unfinished uploaded chunks is not as expected"}, 55 {&fsctx.FileStream{ 56 Mode: fsctx.Append | fsctx.Overwrite, 57 SavePath: "inner/TestHandler_Put.txt", 58 File: io.NopCloser(strings.NewReader("123")), 59 }, ""}, 60 } 61 62 for _, testCase := range testCases { 63 err := handler.Put(context.Background(), testCase.file) 64 if testCase.errContains != "" { 65 asserts.Error(err) 66 asserts.Contains(err.Error(), testCase.errContains) 67 } else { 68 asserts.NoError(err) 69 asserts.True(util.Exists(util.RelativePath(testCase.file.Info().SavePath))) 70 } 71 } 72 } 73 74 func TestDriver_TruncateFailed(t *testing.T) { 75 a := assert.New(t) 76 h := Driver{} 77 a.Error(h.Truncate(context.Background(), "TestDriver_TruncateFailed", 0)) 78 } 79 80 func TestHandler_Delete(t *testing.T) { 81 asserts := assert.New(t) 82 handler := Driver{} 83 ctx := context.Background() 84 filePath := util.RelativePath("TestHandler_Delete.file") 85 86 file, err := os.Create(filePath) 87 asserts.NoError(err) 88 _ = file.Close() 89 list, err := handler.Delete(ctx, []string{"TestHandler_Delete.file"}) 90 asserts.Equal([]string{}, list) 91 asserts.NoError(err) 92 93 file, err = os.Create(filePath) 94 _ = file.Close() 95 file, _ = os.OpenFile(filePath, os.O_RDWR, os.FileMode(0)) 96 asserts.NoError(err) 97 list, err = handler.Delete(ctx, []string{"TestHandler_Delete.file", "test.notexist"}) 98 file.Close() 99 asserts.Equal([]string{}, list) 100 asserts.NoError(err) 101 102 list, err = handler.Delete(ctx, []string{"test.notexist"}) 103 asserts.Equal([]string{}, list) 104 asserts.NoError(err) 105 106 file, err = os.Create(filePath) 107 asserts.NoError(err) 108 list, err = handler.Delete(ctx, []string{"TestHandler_Delete.file"}) 109 _ = file.Close() 110 asserts.Equal([]string{}, list) 111 asserts.NoError(err) 112 } 113 114 func TestHandler_Get(t *testing.T) { 115 asserts := assert.New(t) 116 handler := Driver{} 117 ctx, cancel := context.WithCancel(context.Background()) 118 defer cancel() 119 120 // 成功 121 file, err := os.Create(util.RelativePath("TestHandler_Get.txt")) 122 asserts.NoError(err) 123 _ = file.Close() 124 125 rs, err := handler.Get(ctx, "TestHandler_Get.txt") 126 asserts.NoError(err) 127 asserts.NotNil(rs) 128 129 // 文件不存在 130 131 rs, err = handler.Get(ctx, "TestHandler_Get_notExist.txt") 132 asserts.Error(err) 133 asserts.Nil(rs) 134 } 135 136 func TestHandler_Thumb(t *testing.T) { 137 asserts := assert.New(t) 138 handler := Driver{} 139 ctx := context.Background() 140 file, err := os.Create(util.RelativePath("TestHandler_Thumb._thumb")) 141 asserts.NoError(err) 142 file.Close() 143 144 f := &model.File{ 145 SourceName: "TestHandler_Thumb", 146 MetadataSerialized: map[string]string{ 147 model.ThumbStatusMetadataKey: model.ThumbStatusExist, 148 }, 149 } 150 151 // 正常 152 { 153 thumb, err := handler.Thumb(ctx, f) 154 asserts.NoError(err) 155 asserts.NotNil(thumb.Content) 156 } 157 158 // file 不存在 159 { 160 f.SourceName = "not_exist" 161 _, err := handler.Thumb(ctx, f) 162 asserts.Error(err) 163 asserts.ErrorIs(err, driver.ErrorThumbNotExist) 164 } 165 166 // thumb not exist 167 { 168 f.MetadataSerialized[model.ThumbStatusMetadataKey] = model.ThumbStatusNotExist 169 _, err := handler.Thumb(ctx, f) 170 asserts.Error(err) 171 asserts.ErrorIs(err, driver.ErrorThumbNotExist) 172 } 173 } 174 175 func TestHandler_Source(t *testing.T) { 176 asserts := assert.New(t) 177 handler := Driver{ 178 Policy: &model.Policy{}, 179 } 180 ctx := context.Background() 181 auth.General = auth.HMACAuth{SecretKey: []byte("test")} 182 183 // 成功 184 { 185 file := model.File{ 186 Model: gorm.Model{ 187 ID: 1, 188 }, 189 Name: "test.jpg", 190 } 191 ctx := context.WithValue(ctx, fsctx.FileModelCtx, file) 192 sourceURL, err := handler.Source(ctx, "", 0, false, 0) 193 asserts.NoError(err) 194 asserts.NotEmpty(sourceURL) 195 asserts.Contains(sourceURL, "sign=") 196 } 197 198 // 下载 199 { 200 file := model.File{ 201 Model: gorm.Model{ 202 ID: 1, 203 }, 204 Name: "test.jpg", 205 } 206 ctx := context.WithValue(ctx, fsctx.FileModelCtx, file) 207 sourceURL, err := handler.Source(ctx, "", 0, true, 0) 208 asserts.NoError(err) 209 asserts.NotEmpty(sourceURL) 210 asserts.Contains(sourceURL, "sign=") 211 asserts.Contains(sourceURL, "download") 212 } 213 214 // 无法获取上下文 215 { 216 sourceURL, err := handler.Source(ctx, "", 0, false, 0) 217 asserts.Error(err) 218 asserts.Empty(sourceURL) 219 } 220 221 // 设定了CDN 222 { 223 handler.Policy.BaseURL = "https://cqu.edu.cn" 224 file := model.File{ 225 Model: gorm.Model{ 226 ID: 1, 227 }, 228 Name: "test.jpg", 229 } 230 ctx := context.WithValue(ctx, fsctx.FileModelCtx, file) 231 sourceURL, err := handler.Source(ctx, "", 0, false, 0) 232 asserts.NoError(err) 233 asserts.NotEmpty(sourceURL) 234 asserts.Contains(sourceURL, "sign=") 235 asserts.Contains(sourceURL, "https://cqu.edu.cn") 236 } 237 238 // 设定了CDN,解析失败 239 { 240 handler.Policy.BaseURL = string([]byte{0x7f}) 241 file := model.File{ 242 Model: gorm.Model{ 243 ID: 1, 244 }, 245 Name: "test.jpg", 246 } 247 ctx := context.WithValue(ctx, fsctx.FileModelCtx, file) 248 sourceURL, err := handler.Source(ctx, "", 0, false, 0) 249 asserts.Error(err) 250 asserts.Empty(sourceURL) 251 } 252 } 253 254 func TestHandler_GetDownloadURL(t *testing.T) { 255 asserts := assert.New(t) 256 handler := Driver{Policy: &model.Policy{}} 257 ctx := context.Background() 258 auth.General = auth.HMACAuth{SecretKey: []byte("test")} 259 260 // 成功 261 { 262 file := model.File{ 263 Model: gorm.Model{ 264 ID: 1, 265 }, 266 Name: "test.jpg", 267 } 268 ctx := context.WithValue(ctx, fsctx.FileModelCtx, file) 269 downloadURL, err := handler.Source(ctx, "", 10, true, 0) 270 asserts.NoError(err) 271 asserts.Contains(downloadURL, "sign=") 272 } 273 274 // 无法获取上下文 275 { 276 downloadURL, err := handler.Source(ctx, "", 10, true, 0) 277 asserts.Error(err) 278 asserts.Empty(downloadURL) 279 } 280 } 281 282 func TestHandler_Token(t *testing.T) { 283 asserts := assert.New(t) 284 handler := Driver{ 285 Policy: &model.Policy{}, 286 } 287 ctx := context.Background() 288 upSession := &serializer.UploadSession{SavePath: "TestHandler_Token"} 289 _, err := handler.Token(ctx, 10, upSession, &fsctx.FileStream{}) 290 asserts.NoError(err) 291 292 file, _ := os.Create("TestHandler_Token") 293 defer func() { 294 file.Close() 295 os.Remove("TestHandler_Token") 296 }() 297 298 _, err = handler.Token(ctx, 10, upSession, &fsctx.FileStream{}) 299 asserts.Error(err) 300 asserts.Contains(err.Error(), "already exist") 301 } 302 303 func TestDriver_CancelToken(t *testing.T) { 304 a := assert.New(t) 305 handler := Driver{} 306 a.NoError(handler.CancelToken(context.Background(), &serializer.UploadSession{})) 307 } 308 309 func TestDriver_List(t *testing.T) { 310 asserts := assert.New(t) 311 handler := Driver{} 312 ctx := context.Background() 313 314 // 创建测试目录结构 315 for _, path := range []string{ 316 "test/TestDriver_List/parent.txt", 317 "test/TestDriver_List/parent_folder2/sub2.txt", 318 "test/TestDriver_List/parent_folder1/sub_folder/sub1.txt", 319 "test/TestDriver_List/parent_folder1/sub_folder/sub2.txt", 320 } { 321 f, _ := util.CreatNestedFile(util.RelativePath(path)) 322 f.Close() 323 } 324 325 // 非递归列出 326 { 327 res, err := handler.List(ctx, "test/TestDriver_List", false) 328 asserts.NoError(err) 329 asserts.Len(res, 3) 330 } 331 332 // 递归列出 333 { 334 res, err := handler.List(ctx, "test/TestDriver_List", true) 335 asserts.NoError(err) 336 asserts.Len(res, 7) 337 } 338 }