github.com/qiniu/go-sdk/v7@v7.27.0/storage/resume_uploader_v2_test.go (about) 1 //go:build integration 2 // +build integration 3 4 package storage 5 6 import ( 7 "bytes" 8 "context" 9 "crypto/md5" 10 "encoding/hex" 11 "fmt" 12 "io" 13 "math/rand" 14 "os" 15 "path/filepath" 16 "sync/atomic" 17 "testing" 18 "time" 19 ) 20 21 func TestPutWithoutSizeV2(t *testing.T) { 22 var putRet PutRet 23 putPolicy := PutPolicy{ 24 Scope: testBucket, 25 DeleteAfterDays: 7, 26 } 27 upToken := putPolicy.UploadToken(mac) 28 29 r := rand.New(rand.NewSource(time.Now().UnixNano())) 30 sizes := []int64{ 31 64, 32 1 << blockBits, 33 (1 << blockBits) - 1, 34 (1 << blockBits) + 1, 35 (1 << (blockBits + 4)) + 1, 36 } 37 partSizes := []int64{0, 1 << 20, 1 << 24} 38 39 for _, partSize := range partSizes { 40 for _, size := range sizes { 41 md5Sumer := md5.New() 42 rd := io.TeeReader(&io.LimitedReader{R: r, N: size}, md5Sumer) 43 testKey := fmt.Sprintf("testRPutFileV2Key_%d", r.Int()) 44 err := resumeUploaderV2.PutWithoutSize(context.Background(), &putRet, upToken, testKey, rd, &RputV2Extra{ 45 PartSize: partSize, 46 Notify: func(partNumber int64, ret *UploadPartsRet) { 47 t.Logf("Notify: partNumber: %d, ret: %#v", partNumber, ret) 48 }, 49 NotifyErr: func(partNumber int64, err error) { 50 t.Logf("NotifyErr: partNumber: %d, err: %s", partNumber, err) 51 }, 52 }) 53 if err != nil { 54 t.Fatalf("PutWithoutSize() error, %s", err) 55 } 56 md5Value := hex.EncodeToString(md5Sumer.Sum(nil)) 57 validateMD5(t, testKey, md5Value, size) 58 t.Logf("Size: %d, Part: %d, Key: %s, Hash:%s", size, partSize, putRet.Key, putRet.Hash) 59 } 60 } 61 } 62 63 func TestPutWithSizeV2(t *testing.T) { 64 var putRet PutRet 65 putPolicy := PutPolicy{ 66 Scope: testBucket, 67 DeleteAfterDays: 7, 68 } 69 upToken := putPolicy.UploadToken(mac) 70 71 r := rand.New(rand.NewSource(time.Now().UnixNano())) 72 sizes := []int64{ 73 64, 74 1 << blockBits, 75 (1 << blockBits) - 1, 76 (1 << blockBits) + 1, 77 (1 << (blockBits + 4)) + 1, 78 } 79 partSizes := []int64{0, 1 << 20, 1 << 24} 80 81 hostSelector := 0 82 for _, partSize := range partSizes { 83 hostSelector += 1 84 for _, size := range sizes { 85 hostSelector += 1 86 upHost := "" 87 if hostSelector%3 == 1 { 88 upHost = testUpHost 89 } else { 90 upHost = "https://" + testUpHost 91 } 92 93 data := make([]byte, size) 94 if _, err := io.ReadFull(r, data); err != nil { 95 t.Error(err) 96 } 97 testKey := fmt.Sprintf("testRPutFileV2Key_%d", r.Int()) 98 err := resumeUploaderV2.Put(context.Background(), &putRet, upToken, testKey, bytes.NewReader(data), size, &RputV2Extra{ 99 PartSize: partSize, 100 UpHost: upHost, 101 Notify: func(partNumber int64, ret *UploadPartsRet) { 102 t.Logf("Notify: partNumber: %d, ret: %#v", partNumber, ret) 103 }, 104 NotifyErr: func(partNumber int64, err error) { 105 t.Logf("NotifyErr: partNumber: %d, err: %s", partNumber, err) 106 }, 107 }) 108 if err != nil { 109 t.Fatalf("Put() error, %s", err) 110 } 111 md5ByteArray := md5.Sum(data) 112 md5Value := hex.EncodeToString(md5ByteArray[:]) 113 validateMD5(t, testKey, md5Value, size) 114 t.Logf("Size: %d, Part: %d, Key: %s, Hash:%s", size, partSize, putRet.Key, putRet.Hash) 115 } 116 } 117 for _, partSize := range partSizes { 118 for _, size := range sizes { 119 md5Sumer := md5.New() 120 testKey := fmt.Sprintf("testRPutFileV2Key_%d_*", r.Int()) 121 tmpFile, err := os.CreateTemp("", testKey) 122 if err != nil { 123 t.Error(err) 124 } 125 defer os.Remove(tmpFile.Name()) 126 defer tmpFile.Close() 127 128 if _, err = io.CopyN(tmpFile, io.TeeReader(r, md5Sumer), size); err != nil { 129 t.Error(err) 130 } else if err = tmpFile.Close(); err != nil { 131 t.Error(err) 132 } 133 err = resumeUploaderV2.PutFile(context.Background(), &putRet, upToken, testKey, tmpFile.Name(), &RputV2Extra{ 134 PartSize: partSize, 135 Notify: func(partNumber int64, ret *UploadPartsRet) { 136 t.Logf("Notify: partNumber: %d, ret: %#v", partNumber, ret) 137 }, 138 NotifyErr: func(partNumber int64, err error) { 139 t.Logf("NotifyErr: partNumber: %d, err: %s", partNumber, err) 140 }, 141 }) 142 if err != nil { 143 t.Fatalf("PutFile() error, %s", err) 144 } 145 md5ByteArray := md5Sumer.Sum(nil) 146 md5Value := hex.EncodeToString(md5ByteArray[:]) 147 validateMD5(t, testKey, md5Value, size) 148 t.Logf("Size: %d, Part: %d, Key: %s, Hash:%s", size, partSize, putRet.Key, putRet.Hash) 149 } 150 } 151 } 152 153 func TestPutWithoutKeyV2(t *testing.T) { 154 var putRet PutRet 155 putPolicy := PutPolicy{ 156 Scope: testBucket, 157 DeleteAfterDays: 7, 158 } 159 upToken := putPolicy.UploadToken(mac) 160 161 r := rand.New(rand.NewSource(time.Now().UnixNano())) 162 data := make([]byte, 64) 163 if _, err := io.ReadFull(r, data); err != nil { 164 t.Error(err) 165 } 166 err := resumeUploaderV2.PutWithoutKey(context.Background(), &putRet, upToken, bytes.NewReader(data), int64(len(data)), &RputV2Extra{ 167 Notify: func(partNumber int64, ret *UploadPartsRet) { 168 t.Logf("Notify: partNumber: %d, ret: %#v", partNumber, ret) 169 }, 170 NotifyErr: func(partNumber int64, err error) { 171 t.Logf("NotifyErr: partNumber: %d, err: %s", partNumber, err) 172 }, 173 }) 174 if err != nil { 175 t.Fatalf("PutWithoutKey() error, %s", err) 176 } 177 t.Logf("Key: %s, Hash:%s", putRet.Key, putRet.Hash) 178 179 tmpFile, err := os.CreateTemp("", "") 180 if err != nil { 181 t.Error(err) 182 } 183 if _, err = io.Copy(tmpFile, bytes.NewReader(data)); err != nil { 184 t.Error(err) 185 } else if err = tmpFile.Close(); err != nil { 186 t.Error(err) 187 } 188 err = resumeUploaderV2.PutFileWithoutKey(context.Background(), &putRet, upToken, tmpFile.Name(), &RputV2Extra{ 189 Notify: func(partNumber int64, ret *UploadPartsRet) { 190 t.Logf("Notify: partNumber: %d, ret: %#v", partNumber, ret) 191 }, 192 NotifyErr: func(partNumber int64, err error) { 193 t.Logf("NotifyErr: partNumber: %d, err: %s", partNumber, err) 194 }, 195 }) 196 if err != nil { 197 t.Fatalf("PutWithoutKey() error, %s", err) 198 } 199 t.Logf("Key: %s, Hash:%s", putRet.Key, putRet.Hash) 200 } 201 202 func TestPutWithRecoveryV2(t *testing.T) { 203 var putRet PutRet 204 putPolicy := PutPolicy{ 205 Scope: testBucket, 206 DeleteAfterDays: 7, 207 } 208 upToken := putPolicy.UploadToken(mac) 209 210 r := rand.New(rand.NewSource(time.Now().UnixNano())) 211 testKey := fmt.Sprintf("testRPutFileKey_%d", r.Int()) 212 dirName, err := os.MkdirTemp("", "") 213 if err != nil { 214 t.Fatal(err) 215 } 216 defer os.RemoveAll(dirName) 217 recorder, err := NewFileRecorder(dirName) 218 if err != nil { 219 t.Fatal(err) 220 } 221 222 t.Logf("recorder path:%s", dirName) 223 fileName := filepath.Join(dirName, "originalFile") 224 testFile, err := os.OpenFile(fileName, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) 225 if err != nil { 226 t.Fatal(err) 227 } 228 defer testFile.Close() 229 230 size := int64(4 * (1 << blockBits)) 231 io.CopyN(testFile, r, size) 232 233 for i := 0; i < 4; i++ { 234 ctx, cancelFunc := context.WithCancel(context.Background()) 235 counter := uint32(0) 236 err = resumeUploaderV2.PutFile(ctx, &putRet, upToken, testKey, fileName, &RputV2Extra{ 237 Recorder: recorder, 238 Notify: func(partNumber int64, ret *UploadPartsRet) { 239 t.Logf("Notify: partNumber: %d, ret: %#v", partNumber, ret) 240 if atomic.AddUint32(&counter, 1) >= 2 { 241 cancelFunc() 242 } 243 }, 244 NotifyErr: func(partNumber int64, err error) { 245 t.Logf("NotifyErr: partNumber: %d, err: %s", partNumber, err) 246 }, 247 }) 248 if err == nil { 249 return 250 } 251 } 252 t.Fatal(err) 253 } 254 255 func TestPutWithBackupV2(t *testing.T) { 256 var putRet PutRet 257 putPolicy := PutPolicy{ 258 Scope: testBucket, 259 DeleteAfterDays: 7, 260 } 261 upToken := putPolicy.UploadToken(mac) 262 263 r := rand.New(rand.NewSource(time.Now().UnixNano())) 264 sizes := []int64{ 265 64, 266 1 << blockBits, 267 (1 << blockBits) - 1, 268 (1 << blockBits) + 1, 269 (1 << (blockBits + 4)) + 1, 270 } 271 chunkSizes := []int{0, 1 << 20} 272 273 region, err := GetRegion(mac.AccessKey, testBucket) 274 if err != nil { 275 t.Fatal("get region error:", err) 276 } 277 278 customizedHost := []string{"mock.qiniu.com"} 279 customizedHost = append(customizedHost, region.SrcUpHosts...) 280 region.SrcUpHosts = customizedHost 281 cfg := Config{} 282 cfg.UseCdnDomains = false 283 cfg.Region = region 284 uploader := NewResumeUploaderV2(&cfg) 285 286 hostSelector := 0 287 for _, chunkSize := range chunkSizes { 288 hostSelector += 1 289 for _, size := range sizes { 290 hostSelector += 1 291 data := make([]byte, size) 292 if _, err := io.ReadFull(r, data); err != nil { 293 t.Fatal(err) 294 } 295 testKey := fmt.Sprintf("testRPutFileKey_%d", r.Int()) 296 err := uploader.Put(context.Background(), &putRet, upToken, testKey, bytes.NewReader(data), size, &RputV2Extra{ 297 Notify: func(partNumber int64, ret *UploadPartsRet) { 298 t.Logf("Notify: partNumber: %d, ret: %#v", partNumber, ret) 299 }, 300 NotifyErr: func(partNumber int64, err error) { 301 t.Logf("NotifyErr: partNumber: %d, err: %s", partNumber, err) 302 }, 303 }) 304 if err != nil { 305 t.Fatalf("Put() error, %s", err) 306 } 307 md5ByteArray := md5.Sum(data) 308 md5Value := hex.EncodeToString(md5ByteArray[:]) 309 validateMD5(t, testKey, md5Value, size) 310 t.Logf("Size: %d, Chunk: %d, Key: %s, Hash:%s", size, chunkSize, putRet.Key, putRet.Hash) 311 } 312 } 313 } 314 315 func TestPutWithEmptyKeyV2(t *testing.T) { 316 bucketManager.Delete(testBucket, "") 317 318 var putRet PutRet 319 putPolicy := PutPolicy{ 320 Scope: testBucket + ":", 321 DeleteAfterDays: 7, 322 } 323 upToken := putPolicy.UploadToken(mac) 324 325 r := rand.New(rand.NewSource(time.Now().UnixNano())) 326 data := make([]byte, 64) 327 if _, err := io.ReadFull(r, data); err != nil { 328 t.Error(err) 329 } 330 err := resumeUploaderV2.Put(context.Background(), &putRet, upToken, "", bytes.NewReader(data), int64(len(data)), &RputV2Extra{ 331 Notify: func(partNumber int64, ret *UploadPartsRet) { 332 t.Logf("Notify: partNumber: %d, ret: %#v", partNumber, ret) 333 }, 334 NotifyErr: func(partNumber int64, err error) { 335 t.Logf("NotifyErr: partNumber: %d, err: %s", partNumber, err) 336 }, 337 }) 338 if err != nil { 339 t.Fatalf("Put() error, %s", err) 340 } 341 t.Logf("Key: %s, Hash:%s", putRet.Key, putRet.Hash) 342 }