1package azblob 2 3import ( 4 "context" 5 "crypto/md5" 6 "io/ioutil" 7 8 "bytes" 9 "strings" 10 "time" 11 12 chk "gopkg.in/check.v1" 13) 14 15func (s *aztestsSuite) TestPutGetPages(c *chk.C) { 16 bsu := getBSU() 17 container, _ := createNewContainer(c, bsu) 18 defer delContainer(c, container) 19 20 blob, _ := createNewPageBlob(c, container) 21 22 pageRange := PageRange{Start: 0, End: 1023} 23 putResp, err := blob.UploadPages(context.Background(), 0, getReaderToRandomBytes(1024), PageBlobAccessConditions{}, nil, ClientProvidedKeyOptions{}) 24 c.Assert(err, chk.IsNil) 25 c.Assert(putResp.Response().StatusCode, chk.Equals, 201) 26 c.Assert(putResp.LastModified().IsZero(), chk.Equals, false) 27 c.Assert(putResp.ETag(), chk.Not(chk.Equals), ETagNone) 28 c.Assert(putResp.ContentMD5(), chk.Not(chk.Equals), "") 29 c.Assert(putResp.BlobSequenceNumber(), chk.Equals, int64(0)) 30 c.Assert(putResp.RequestID(), chk.Not(chk.Equals), "") 31 c.Assert(putResp.Version(), chk.Not(chk.Equals), "") 32 c.Assert(putResp.Date().IsZero(), chk.Equals, false) 33 34 pageList, err := blob.GetPageRanges(context.Background(), 0, 1023, BlobAccessConditions{}) 35 c.Assert(err, chk.IsNil) 36 c.Assert(pageList.Response().StatusCode, chk.Equals, 200) 37 c.Assert(pageList.LastModified().IsZero(), chk.Equals, false) 38 c.Assert(pageList.ETag(), chk.Not(chk.Equals), ETagNone) 39 c.Assert(pageList.BlobContentLength(), chk.Equals, int64(512*10)) 40 c.Assert(pageList.RequestID(), chk.Not(chk.Equals), "") 41 c.Assert(pageList.Version(), chk.Not(chk.Equals), "") 42 c.Assert(pageList.Date().IsZero(), chk.Equals, false) 43 c.Assert(pageList.PageRange, chk.HasLen, 1) 44 c.Assert(pageList.PageRange[0], chk.DeepEquals, pageRange) 45} 46 47func (s *aztestsSuite) TestUploadPagesFromURL(c *chk.C) { 48 bsu := getBSU() 49 credential, err := getGenericCredential("") 50 if err != nil { 51 c.Fatal("Invalid credential") 52 } 53 container, _ := createNewContainer(c, bsu) 54 defer delContainer(c, container) 55 56 testSize := 4 * 1024 * 1024 // 4MB 57 r, sourceData := getRandomDataAndReader(testSize) 58 ctx := context.Background() // Use default Background context 59 srcBlob, _ := createNewPageBlobWithSize(c, container, int64(testSize)) 60 destBlob, _ := createNewPageBlobWithSize(c, container, int64(testSize)) 61 62 // Prepare source blob for copy. 63 uploadSrcResp1, err := srcBlob.UploadPages(ctx, 0, r, PageBlobAccessConditions{}, nil, ClientProvidedKeyOptions{}) 64 c.Assert(err, chk.IsNil) 65 c.Assert(uploadSrcResp1.Response().StatusCode, chk.Equals, 201) 66 67 // Get source blob URL with SAS for UploadPagesFromURL. 68 srcBlobParts := NewBlobURLParts(srcBlob.URL()) 69 70 srcBlobParts.SAS, err = BlobSASSignatureValues{ 71 Protocol: SASProtocolHTTPS, // Users MUST use HTTPS (not HTTP) 72 ExpiryTime: time.Now().UTC().Add(48 * time.Hour), // 48-hours before expiration 73 ContainerName: srcBlobParts.ContainerName, 74 BlobName: srcBlobParts.BlobName, 75 Permissions: BlobSASPermissions{Read: true}.String(), 76 }.NewSASQueryParameters(credential) 77 if err != nil { 78 c.Fatal(err) 79 } 80 81 srcBlobURLWithSAS := srcBlobParts.URL() 82 83 // Upload page from URL. 84 pResp1, err := destBlob.UploadPagesFromURL(ctx, srcBlobURLWithSAS, 0, 0, int64(testSize), nil, PageBlobAccessConditions{}, ModifiedAccessConditions{}, ClientProvidedKeyOptions{}) 85 c.Assert(err, chk.IsNil) 86 c.Assert(pResp1.ETag(), chk.NotNil) 87 c.Assert(pResp1.LastModified(), chk.NotNil) 88 c.Assert(pResp1.Response().StatusCode, chk.Equals, 201) 89 c.Assert(pResp1.ContentMD5(), chk.Not(chk.Equals), "") 90 c.Assert(pResp1.RequestID(), chk.Not(chk.Equals), "") 91 c.Assert(pResp1.Version(), chk.Not(chk.Equals), "") 92 c.Assert(pResp1.Date().IsZero(), chk.Equals, false) 93 94 // Check data integrity through downloading. 95 downloadResp, err := destBlob.BlobURL.Download(ctx, 0, CountToEnd, BlobAccessConditions{}, false, ClientProvidedKeyOptions{}) 96 c.Assert(err, chk.IsNil) 97 destData, err := ioutil.ReadAll(downloadResp.Body(RetryReaderOptions{})) 98 c.Assert(err, chk.IsNil) 99 c.Assert(destData, chk.DeepEquals, sourceData) 100} 101 102func (s *aztestsSuite) TestUploadPagesFromURLWithMD5(c *chk.C) { 103 bsu := getBSU() 104 credential, err := getGenericCredential("") 105 if err != nil { 106 c.Fatal("Invalid credential") 107 } 108 container, _ := createNewContainer(c, bsu) 109 defer delContainer(c, container) 110 111 testSize := 4 * 1024 * 1024 // 4MB 112 r, sourceData := getRandomDataAndReader(testSize) 113 md5Value := md5.Sum(sourceData) 114 ctx := context.Background() // Use default Background context 115 srcBlob, _ := createNewPageBlobWithSize(c, container, int64(testSize)) 116 destBlob, _ := createNewPageBlobWithSize(c, container, int64(testSize)) 117 118 // Prepare source blob for copy. 119 uploadSrcResp1, err := srcBlob.UploadPages(ctx, 0, r, PageBlobAccessConditions{}, nil, ClientProvidedKeyOptions{}) 120 c.Assert(err, chk.IsNil) 121 c.Assert(uploadSrcResp1.Response().StatusCode, chk.Equals, 201) 122 123 // Get source blob URL with SAS for UploadPagesFromURL. 124 srcBlobParts := NewBlobURLParts(srcBlob.URL()) 125 126 srcBlobParts.SAS, err = BlobSASSignatureValues{ 127 Protocol: SASProtocolHTTPS, // Users MUST use HTTPS (not HTTP) 128 ExpiryTime: time.Now().UTC().Add(48 * time.Hour), // 48-hours before expiration 129 ContainerName: srcBlobParts.ContainerName, 130 BlobName: srcBlobParts.BlobName, 131 Permissions: BlobSASPermissions{Read: true}.String(), 132 }.NewSASQueryParameters(credential) 133 if err != nil { 134 c.Fatal(err) 135 } 136 137 srcBlobURLWithSAS := srcBlobParts.URL() 138 139 // Upload page from URL with MD5. 140 pResp1, err := destBlob.UploadPagesFromURL(ctx, srcBlobURLWithSAS, 0, 0, int64(testSize), md5Value[:], PageBlobAccessConditions{}, ModifiedAccessConditions{}, ClientProvidedKeyOptions{}) 141 c.Assert(err, chk.IsNil) 142 c.Assert(pResp1.ETag(), chk.NotNil) 143 c.Assert(pResp1.LastModified(), chk.NotNil) 144 c.Assert(pResp1.Response().StatusCode, chk.Equals, 201) 145 c.Assert(pResp1.RequestID(), chk.Not(chk.Equals), "") 146 c.Assert(pResp1.Version(), chk.Not(chk.Equals), "") 147 c.Assert(pResp1.Date().IsZero(), chk.Equals, false) 148 c.Assert(pResp1.ContentMD5(), chk.DeepEquals, md5Value[:]) 149 c.Assert(pResp1.BlobSequenceNumber(), chk.Equals, int64(0)) 150 151 // Check data integrity through downloading. 152 downloadResp, err := destBlob.BlobURL.Download(ctx, 0, CountToEnd, BlobAccessConditions{}, false, ClientProvidedKeyOptions{}) 153 c.Assert(err, chk.IsNil) 154 destData, err := ioutil.ReadAll(downloadResp.Body(RetryReaderOptions{})) 155 c.Assert(err, chk.IsNil) 156 c.Assert(destData, chk.DeepEquals, sourceData) 157 158 // Upload page from URL with bad MD5 159 _, badMD5 := getRandomDataAndReader(16) 160 _, err = destBlob.UploadPagesFromURL(ctx, srcBlobURLWithSAS, 0, 0, int64(testSize), badMD5[:], PageBlobAccessConditions{}, ModifiedAccessConditions{}, ClientProvidedKeyOptions{}) 161 validateStorageError(c, err, ServiceCodeMd5Mismatch) 162} 163 164func (s *aztestsSuite) TestClearDiffPages(c *chk.C) { 165 bsu := getBSU() 166 container, _ := createNewContainer(c, bsu) 167 defer delContainer(c, container) 168 169 blob, _ := createNewPageBlob(c, container) 170 _, err := blob.UploadPages(context.Background(), 0, getReaderToRandomBytes(2048), PageBlobAccessConditions{}, nil, ClientProvidedKeyOptions{}) 171 c.Assert(err, chk.IsNil) 172 173 snapshotResp, err := blob.CreateSnapshot(context.Background(), nil, BlobAccessConditions{}, ClientProvidedKeyOptions{}) 174 c.Assert(err, chk.IsNil) 175 176 _, err = blob.UploadPages(context.Background(), 2048, getReaderToRandomBytes(2048), PageBlobAccessConditions{}, nil, ClientProvidedKeyOptions{}) 177 c.Assert(err, chk.IsNil) 178 179 pageList, err := blob.GetPageRangesDiff(context.Background(), 0, 4096, snapshotResp.Snapshot(), BlobAccessConditions{}) 180 c.Assert(err, chk.IsNil) 181 c.Assert(pageList.PageRange, chk.HasLen, 1) 182 c.Assert(pageList.PageRange[0].Start, chk.Equals, int64(2048)) 183 c.Assert(pageList.PageRange[0].End, chk.Equals, int64(4095)) 184 185 clearResp, err := blob.ClearPages(context.Background(), 2048, 2048, PageBlobAccessConditions{}, ClientProvidedKeyOptions{}) 186 c.Assert(err, chk.IsNil) 187 c.Assert(clearResp.Response().StatusCode, chk.Equals, 201) 188 189 pageList, err = blob.GetPageRangesDiff(context.Background(), 0, 4095, snapshotResp.Snapshot(), BlobAccessConditions{}) 190 c.Assert(err, chk.IsNil) 191 c.Assert(pageList.PageRange, chk.HasLen, 0) 192} 193 194func (s *aztestsSuite) TestIncrementalCopy(c *chk.C) { 195 bsu := getBSU() 196 container, _ := createNewContainer(c, bsu) 197 defer delContainer(c, container) 198 _, err := container.SetAccessPolicy(context.Background(), PublicAccessBlob, nil, ContainerAccessConditions{}) 199 c.Assert(err, chk.IsNil) 200 201 srcBlob, _ := createNewPageBlob(c, container) 202 _, err = srcBlob.UploadPages(context.Background(), 0, getReaderToRandomBytes(1024), PageBlobAccessConditions{}, nil, ClientProvidedKeyOptions{}) 203 c.Assert(err, chk.IsNil) 204 snapshotResp, err := srcBlob.CreateSnapshot(context.Background(), nil, BlobAccessConditions{}, ClientProvidedKeyOptions{}) 205 c.Assert(err, chk.IsNil) 206 207 dstBlob := container.NewPageBlobURL(generateBlobName()) 208 209 resp, err := dstBlob.StartCopyIncremental(context.Background(), srcBlob.URL(), snapshotResp.Snapshot(), BlobAccessConditions{}) 210 c.Assert(err, chk.IsNil) 211 c.Assert(resp.Response().StatusCode, chk.Equals, 202) 212 c.Assert(resp.LastModified().IsZero(), chk.Equals, false) 213 c.Assert(resp.ETag(), chk.Not(chk.Equals), ETagNone) 214 c.Assert(resp.RequestID(), chk.Not(chk.Equals), "") 215 c.Assert(resp.Version(), chk.Not(chk.Equals), "") 216 c.Assert(resp.Date().IsZero(), chk.Equals, false) 217 c.Assert(resp.CopyID(), chk.Not(chk.Equals), "") 218 c.Assert(resp.CopyStatus(), chk.Equals, CopyStatusPending) 219 220 waitForIncrementalCopy(c, dstBlob, resp) 221} 222 223func (s *aztestsSuite) TestResizePageBlob(c *chk.C) { 224 bsu := getBSU() 225 container, _ := createNewContainer(c, bsu) 226 defer delContainer(c, container) 227 228 blob, _ := createNewPageBlob(c, container) 229 resp, err := blob.Resize(context.Background(), 2048, BlobAccessConditions{}, ClientProvidedKeyOptions{}) 230 c.Assert(err, chk.IsNil) 231 c.Assert(resp.Response().StatusCode, chk.Equals, 200) 232 233 resp, err = blob.Resize(context.Background(), 8192, BlobAccessConditions{}, ClientProvidedKeyOptions{}) 234 c.Assert(err, chk.IsNil) 235 c.Assert(resp.Response().StatusCode, chk.Equals, 200) 236 237 resp2, err := blob.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{}) 238 c.Assert(err, chk.IsNil) 239 c.Assert(resp2.ContentLength(), chk.Equals, int64(8192)) 240} 241 242func (s *aztestsSuite) TestPageSequenceNumbers(c *chk.C) { 243 bsu := getBSU() 244 container, _ := createNewContainer(c, bsu) 245 blob, _ := createNewPageBlob(c, container) 246 247 defer delContainer(c, container) 248 249 resp, err := blob.UpdateSequenceNumber(context.Background(), SequenceNumberActionIncrement, 0, BlobAccessConditions{}) 250 c.Assert(err, chk.IsNil) 251 c.Assert(resp.Response().StatusCode, chk.Equals, 200) 252 253 resp, err = blob.UpdateSequenceNumber(context.Background(), SequenceNumberActionMax, 7, BlobAccessConditions{}) 254 c.Assert(err, chk.IsNil) 255 c.Assert(resp.Response().StatusCode, chk.Equals, 200) 256 257 resp, err = blob.UpdateSequenceNumber(context.Background(), SequenceNumberActionUpdate, 11, BlobAccessConditions{}) 258 c.Assert(err, chk.IsNil) 259 c.Assert(resp.Response().StatusCode, chk.Equals, 200) 260} 261 262func (s *aztestsSuite) TestPutPagesWithMD5(c *chk.C) { 263 bsu := getBSU() 264 container, _ := createNewContainer(c, bsu) 265 defer delContainer(c, container) 266 267 blob, _ := createNewPageBlob(c, container) 268 269 // put page with valid MD5 270 readerToBody, body := getRandomDataAndReader(1024) 271 md5Value := md5.Sum(body) 272 putResp, err := blob.UploadPages(context.Background(), 0, readerToBody, PageBlobAccessConditions{}, md5Value[:], ClientProvidedKeyOptions{}) 273 c.Assert(err, chk.IsNil) 274 c.Assert(putResp.Response().StatusCode, chk.Equals, 201) 275 c.Assert(putResp.LastModified().IsZero(), chk.Equals, false) 276 c.Assert(putResp.ETag(), chk.Not(chk.Equals), ETagNone) 277 c.Assert(putResp.ContentMD5(), chk.DeepEquals, md5Value[:]) 278 c.Assert(putResp.BlobSequenceNumber(), chk.Equals, int64(0)) 279 c.Assert(putResp.RequestID(), chk.Not(chk.Equals), "") 280 c.Assert(putResp.Version(), chk.Not(chk.Equals), "") 281 c.Assert(putResp.Date().IsZero(), chk.Equals, false) 282 283 // put page with bad MD5 284 readerToBody, body = getRandomDataAndReader(1024) 285 _, badMD5 := getRandomDataAndReader(16) 286 putResp, err = blob.UploadPages(context.Background(), 0, readerToBody, PageBlobAccessConditions{}, badMD5[:], ClientProvidedKeyOptions{}) 287 validateStorageError(c, err, ServiceCodeMd5Mismatch) 288} 289 290func (s *aztestsSuite) TestBlobCreatePageSizeInvalid(c *chk.C) { 291 bsu := getBSU() 292 containerURL, _ := createNewContainer(c, bsu) 293 defer deleteContainer(c, containerURL) 294 blobURL, _ := getPageBlobURL(c, containerURL) 295 296 _, err := blobURL.Create(ctx, 1, 0, BlobHTTPHeaders{}, nil, BlobAccessConditions{}, DefaultPremiumBlobAccessTier, nil, ClientProvidedKeyOptions{}) 297 validateStorageError(c, err, ServiceCodeInvalidHeaderValue) 298} 299 300func (s *aztestsSuite) TestBlobCreatePageSequenceInvalid(c *chk.C) { 301 bsu := getBSU() 302 containerURL, _ := createNewContainer(c, bsu) 303 defer deleteContainer(c, containerURL) 304 blobURL, _ := getPageBlobURL(c, containerURL) 305 306 _, err := blobURL.Create(ctx, PageBlobPageBytes, -1, BlobHTTPHeaders{}, nil, BlobAccessConditions{}, DefaultPremiumBlobAccessTier, nil, ClientProvidedKeyOptions{}) 307 c.Assert(err, chk.Not(chk.IsNil)) 308} 309 310func (s *aztestsSuite) TestBlobCreatePageMetadataNonEmpty(c *chk.C) { 311 bsu := getBSU() 312 containerURL, _ := createNewContainer(c, bsu) 313 defer deleteContainer(c, containerURL) 314 blobURL, _ := getPageBlobURL(c, containerURL) 315 316 _, err := blobURL.Create(ctx, PageBlobPageBytes, 0, BlobHTTPHeaders{}, basicMetadata, BlobAccessConditions{}, DefaultPremiumBlobAccessTier, nil, ClientProvidedKeyOptions{}) 317 318 resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{}) 319 c.Assert(err, chk.IsNil) 320 c.Assert(resp.NewMetadata(), chk.DeepEquals, basicMetadata) 321} 322 323func (s *aztestsSuite) TestBlobCreatePageMetadataEmpty(c *chk.C) { 324 bsu := getBSU() 325 containerURL, _ := createNewContainer(c, bsu) 326 defer deleteContainer(c, containerURL) 327 blobURL, _ := getPageBlobURL(c, containerURL) 328 329 _, err := blobURL.Create(ctx, PageBlobPageBytes, 0, BlobHTTPHeaders{}, Metadata{}, BlobAccessConditions{}, DefaultPremiumBlobAccessTier, nil, ClientProvidedKeyOptions{}) 330 331 resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{}) 332 c.Assert(err, chk.IsNil) 333 c.Assert(resp.NewMetadata(), chk.HasLen, 0) 334} 335 336func (s *aztestsSuite) TestBlobCreatePageMetadataInvalid(c *chk.C) { 337 bsu := getBSU() 338 containerURL, _ := createNewContainer(c, bsu) 339 defer deleteContainer(c, containerURL) 340 blobURL, _ := getPageBlobURL(c, containerURL) 341 342 _, err := blobURL.Create(ctx, PageBlobPageBytes, 0, BlobHTTPHeaders{}, Metadata{"In valid1": "bar"}, BlobAccessConditions{}, PremiumPageBlobAccessTierNone, nil, ClientProvidedKeyOptions{}) 343 c.Assert(strings.Contains(err.Error(), invalidHeaderErrorSubstring), chk.Equals, true) 344 345} 346 347func (s *aztestsSuite) TestBlobCreatePageHTTPHeaders(c *chk.C) { 348 bsu := getBSU() 349 containerURL, _ := createNewContainer(c, bsu) 350 defer deleteContainer(c, containerURL) 351 blobURL, _ := getPageBlobURL(c, containerURL) 352 353 _, err := blobURL.Create(ctx, PageBlobPageBytes, 0, basicHeaders, nil, BlobAccessConditions{}, PremiumPageBlobAccessTierNone, nil, ClientProvidedKeyOptions{}) 354 c.Assert(err, chk.IsNil) 355 356 resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{}) 357 c.Assert(err, chk.IsNil) 358 h := resp.NewHTTPHeaders() 359 c.Assert(h, chk.DeepEquals, basicHeaders) 360} 361 362func validatePageBlobPut(c *chk.C, blobURL PageBlobURL) { 363 resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{}) 364 c.Assert(err, chk.IsNil) 365 c.Assert(resp.NewMetadata(), chk.DeepEquals, basicMetadata) 366} 367 368func (s *aztestsSuite) TestBlobCreatePageIfModifiedSinceTrue(c *chk.C) { 369 bsu := getBSU() 370 containerURL, _ := createNewContainer(c, bsu) 371 defer deleteContainer(c, containerURL) 372 blobURL, _ := createNewPageBlob(c, containerURL) // Originally created without metadata 373 374 currentTime := getRelativeTimeGMT(-10) 375 376 _, err := blobURL.Create(ctx, PageBlobPageBytes, 0, BlobHTTPHeaders{}, basicMetadata, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}}, DefaultPremiumBlobAccessTier, nil, ClientProvidedKeyOptions{}) 377 c.Assert(err, chk.IsNil) 378 379 validatePageBlobPut(c, blobURL) 380} 381 382func (s *aztestsSuite) TestBlobCreatePageIfModifiedSinceFalse(c *chk.C) { 383 bsu := getBSU() 384 containerURL, _ := createNewContainer(c, bsu) 385 defer deleteContainer(c, containerURL) 386 blobURL, _ := createNewPageBlob(c, containerURL) // Originally created without metadata 387 388 currentTime := getRelativeTimeGMT(10) 389 390 _, err := blobURL.Create(ctx, PageBlobPageBytes, 0, BlobHTTPHeaders{}, basicMetadata, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}}, DefaultPremiumBlobAccessTier, nil, ClientProvidedKeyOptions{}) 391 validateStorageError(c, err, ServiceCodeConditionNotMet) 392} 393 394func (s *aztestsSuite) TestBlobCreatePageIfUnmodifiedSinceTrue(c *chk.C) { 395 bsu := getBSU() 396 containerURL, _ := createNewContainer(c, bsu) 397 defer deleteContainer(c, containerURL) 398 blobURL, _ := createNewPageBlob(c, containerURL) // Originally created without metadata 399 400 currentTime := getRelativeTimeGMT(10) 401 402 _, err := blobURL.Create(ctx, PageBlobPageBytes, 0, BlobHTTPHeaders{}, basicMetadata, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}}, DefaultPremiumBlobAccessTier, nil, ClientProvidedKeyOptions{}) 403 c.Assert(err, chk.IsNil) 404 405 validatePageBlobPut(c, blobURL) 406} 407 408func (s *aztestsSuite) TestBlobCreatePageIfUnmodifiedSinceFalse(c *chk.C) { 409 bsu := getBSU() 410 containerURL, _ := createNewContainer(c, bsu) 411 defer deleteContainer(c, containerURL) 412 blobURL, _ := createNewPageBlob(c, containerURL) // Originally created without metadata 413 414 currentTime := getRelativeTimeGMT(-10) 415 416 _, err := blobURL.Create(ctx, PageBlobPageBytes, 0, BlobHTTPHeaders{}, basicMetadata, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}}, DefaultPremiumBlobAccessTier, nil, ClientProvidedKeyOptions{}) 417 validateStorageError(c, err, ServiceCodeConditionNotMet) 418} 419 420func (s *aztestsSuite) TestBlobCreatePageIfMatchTrue(c *chk.C) { 421 bsu := getBSU() 422 containerURL, _ := createNewContainer(c, bsu) 423 defer deleteContainer(c, containerURL) 424 blobURL, _ := createNewPageBlob(c, containerURL) // Originally created without metadata 425 426 resp, _ := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{}) 427 428 _, err := blobURL.Create(ctx, PageBlobPageBytes, 0, BlobHTTPHeaders{}, basicMetadata, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: resp.ETag()}}, PremiumPageBlobAccessTierNone, nil, ClientProvidedKeyOptions{}) 429 c.Assert(err, chk.IsNil) 430 431 validatePageBlobPut(c, blobURL) 432} 433 434func (s *aztestsSuite) TestBlobCreatePageIfMatchFalse(c *chk.C) { 435 bsu := getBSU() 436 containerURL, _ := createNewContainer(c, bsu) 437 defer deleteContainer(c, containerURL) 438 blobURL, _ := createNewPageBlob(c, containerURL) // Originally created without metadata 439 440 _, err := blobURL.Create(ctx, PageBlobPageBytes, 0, BlobHTTPHeaders{}, basicMetadata, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: ETag("garbage")}}, PremiumPageBlobAccessTierNone, nil, ClientProvidedKeyOptions{}) 441 validateStorageError(c, err, ServiceCodeConditionNotMet) 442} 443 444func (s *aztestsSuite) TestBlobCreatePageIfNoneMatchTrue(c *chk.C) { 445 bsu := getBSU() 446 containerURL, _ := createNewContainer(c, bsu) 447 defer deleteContainer(c, containerURL) 448 blobURL, _ := createNewPageBlob(c, containerURL) // Originally created without metadata 449 450 _, err := blobURL.Create(ctx, PageBlobPageBytes, 0, BlobHTTPHeaders{}, basicMetadata, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfNoneMatch: ETag("garbage")}}, PremiumPageBlobAccessTierNone, nil, ClientProvidedKeyOptions{}) 451 c.Assert(err, chk.IsNil) 452 453 validatePageBlobPut(c, blobURL) 454} 455 456func (s *aztestsSuite) TestBlobCreatePageIfNoneMatchFalse(c *chk.C) { 457 bsu := getBSU() 458 containerURL, _ := createNewContainer(c, bsu) 459 defer deleteContainer(c, containerURL) 460 blobURL, _ := createNewPageBlob(c, containerURL) // Originally created without metadata 461 462 resp, _ := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{}) 463 464 _, err := blobURL.Create(ctx, PageBlobPageBytes, 0, BlobHTTPHeaders{}, basicMetadata, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfNoneMatch: resp.ETag()}}, DefaultPremiumBlobAccessTier, nil, ClientProvidedKeyOptions{}) 465 466 validateStorageError(c, err, ServiceCodeConditionNotMet) 467} 468 469func (s *aztestsSuite) TestBlobPutPagesInvalidRange(c *chk.C) { 470 bsu := getBSU() 471 containerURL, _ := createNewContainer(c, bsu) 472 defer deleteContainer(c, containerURL) 473 blobURL, _ := createNewPageBlob(c, containerURL) 474 475 _, err := blobURL.UploadPages(ctx, 0, strings.NewReader(blockBlobDefaultData), PageBlobAccessConditions{}, nil, ClientProvidedKeyOptions{}) 476 c.Assert(err, chk.Not(chk.IsNil)) 477} 478 479func (s *aztestsSuite) TestBlobPutPagesNilBody(c *chk.C) { 480 bsu := getBSU() 481 containerURL, _ := createNewContainer(c, bsu) 482 defer deleteContainer(c, containerURL) 483 blobURL, _ := createNewPageBlob(c, containerURL) 484 485 _, err := blobURL.UploadPages(ctx, 0, nil, PageBlobAccessConditions{}, nil, ClientProvidedKeyOptions{}) 486 c.Assert(err, chk.Not(chk.IsNil)) 487} 488 489func (s *aztestsSuite) TestBlobPutPagesEmptyBody(c *chk.C) { 490 bsu := getBSU() 491 containerURL, _ := createNewContainer(c, bsu) 492 defer deleteContainer(c, containerURL) 493 blobURL, _ := createNewPageBlob(c, containerURL) 494 495 _, err := blobURL.UploadPages(ctx, 0, bytes.NewReader([]byte{}), PageBlobAccessConditions{}, nil, ClientProvidedKeyOptions{}) 496 c.Assert(err, chk.Not(chk.IsNil)) 497} 498 499func (s *aztestsSuite) TestBlobPutPagesNonExistantBlob(c *chk.C) { 500 bsu := getBSU() 501 containerURL, _ := createNewContainer(c, bsu) 502 defer deleteContainer(c, containerURL) 503 blobURL, _ := getPageBlobURL(c, containerURL) 504 505 _, err := blobURL.UploadPages(ctx, 0, getReaderToRandomBytes(PageBlobPageBytes), PageBlobAccessConditions{}, nil, ClientProvidedKeyOptions{}) 506 validateStorageError(c, err, ServiceCodeBlobNotFound) 507} 508 509func validateUploadPages(c *chk.C, blobURL PageBlobURL) { 510 // This will only validate a single put page at 0-PageBlobPageBytes-1 511 resp, err := blobURL.GetPageRanges(ctx, 0, 0, BlobAccessConditions{}) 512 c.Assert(err, chk.IsNil) 513 c.Assert(resp.PageRange[0], chk.Equals, PageRange{Start: 0, End: PageBlobPageBytes - 1}) 514} 515 516func (s *aztestsSuite) TestBlobPutPagesIfModifiedSinceTrue(c *chk.C) { 517 bsu := getBSU() 518 containerURL, _ := createNewContainer(c, bsu) 519 defer deleteContainer(c, containerURL) 520 blobURL, _ := createNewPageBlob(c, containerURL) 521 522 currentTime := getRelativeTimeGMT(-10) 523 524 _, err := blobURL.UploadPages(ctx, 0, getReaderToRandomBytes(PageBlobPageBytes), PageBlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}}, nil, ClientProvidedKeyOptions{}) 525 c.Assert(err, chk.IsNil) 526 527 validateUploadPages(c, blobURL) 528} 529 530func (s *aztestsSuite) TestBlobPutPagesIfModifiedSinceFalse(c *chk.C) { 531 bsu := getBSU() 532 containerURL, _ := createNewContainer(c, bsu) 533 defer deleteContainer(c, containerURL) 534 blobURL, _ := createNewPageBlob(c, containerURL) 535 536 currentTime := getRelativeTimeGMT(10) 537 538 _, err := blobURL.UploadPages(ctx, 0, getReaderToRandomBytes(PageBlobPageBytes), PageBlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}}, nil, ClientProvidedKeyOptions{}) 539 validateStorageError(c, err, ServiceCodeConditionNotMet) 540} 541 542func (s *aztestsSuite) TestBlobPutPagesIfUnmodifiedSinceTrue(c *chk.C) { 543 bsu := getBSU() 544 containerURL, _ := createNewContainer(c, bsu) 545 defer deleteContainer(c, containerURL) 546 blobURL, _ := createNewPageBlob(c, containerURL) 547 548 currentTime := getRelativeTimeGMT(10) 549 550 _, err := blobURL.UploadPages(ctx, 0, getReaderToRandomBytes(PageBlobPageBytes), PageBlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}}, nil, ClientProvidedKeyOptions{}) 551 c.Assert(err, chk.IsNil) 552 553 validateUploadPages(c, blobURL) 554} 555 556func (s *aztestsSuite) TestBlobPutPagesIfUnmodifiedSinceFalse(c *chk.C) { 557 bsu := getBSU() 558 containerURL, _ := createNewContainer(c, bsu) 559 defer deleteContainer(c, containerURL) 560 blobURL, _ := createNewPageBlob(c, containerURL) 561 562 currentTime := getRelativeTimeGMT(-10) 563 564 _, err := blobURL.UploadPages(ctx, 0, getReaderToRandomBytes(PageBlobPageBytes), PageBlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}}, nil, ClientProvidedKeyOptions{}) 565 validateStorageError(c, err, ServiceCodeConditionNotMet) 566} 567 568func (s *aztestsSuite) TestBlobPutPagesIfMatchTrue(c *chk.C) { 569 bsu := getBSU() 570 containerURL, _ := createNewContainer(c, bsu) 571 defer deleteContainer(c, containerURL) 572 blobURL, _ := createNewPageBlob(c, containerURL) 573 574 resp, _ := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{}) 575 576 _, err := blobURL.UploadPages(ctx, 0, getReaderToRandomBytes(PageBlobPageBytes), PageBlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: resp.ETag()}}, nil, ClientProvidedKeyOptions{}) 577 c.Assert(err, chk.IsNil) 578 579 validateUploadPages(c, blobURL) 580} 581 582func (s *aztestsSuite) TestBlobPutPagesIfMatchFalse(c *chk.C) { 583 bsu := getBSU() 584 containerURL, _ := createNewContainer(c, bsu) 585 defer deleteContainer(c, containerURL) 586 blobURL, _ := createNewPageBlob(c, containerURL) 587 588 _, err := blobURL.UploadPages(ctx, 0, getReaderToRandomBytes(PageBlobPageBytes), PageBlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: ETag("garbage")}}, nil, ClientProvidedKeyOptions{}) 589 validateStorageError(c, err, ServiceCodeConditionNotMet) 590} 591 592func (s *aztestsSuite) TestBlobPutPagesIfNoneMatchTrue(c *chk.C) { 593 bsu := getBSU() 594 containerURL, _ := createNewContainer(c, bsu) 595 defer deleteContainer(c, containerURL) 596 blobURL, _ := createNewPageBlob(c, containerURL) 597 598 _, err := blobURL.UploadPages(ctx, 0, getReaderToRandomBytes(PageBlobPageBytes), PageBlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfNoneMatch: ETag("garbage")}}, nil, ClientProvidedKeyOptions{}) 599 c.Assert(err, chk.IsNil) 600 601 validateUploadPages(c, blobURL) 602} 603 604func (s *aztestsSuite) TestBlobPutPagesIfNoneMatchFalse(c *chk.C) { 605 bsu := getBSU() 606 containerURL, _ := createNewContainer(c, bsu) 607 defer deleteContainer(c, containerURL) 608 blobURL, _ := createNewPageBlob(c, containerURL) 609 610 resp, _ := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{}) 611 612 _, err := blobURL.UploadPages(ctx, 0, getReaderToRandomBytes(PageBlobPageBytes), PageBlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfNoneMatch: resp.ETag()}}, nil, ClientProvidedKeyOptions{}) 613 validateStorageError(c, err, ServiceCodeConditionNotMet) 614} 615 616func (s *aztestsSuite) TestBlobPutPagesIfSequenceNumberLessThanTrue(c *chk.C) { 617 bsu := getBSU() 618 containerURL, _ := createNewContainer(c, bsu) 619 defer deleteContainer(c, containerURL) 620 blobURL, _ := createNewPageBlob(c, containerURL) 621 622 _, err := blobURL.UploadPages(ctx, 0, getReaderToRandomBytes(PageBlobPageBytes), PageBlobAccessConditions{SequenceNumberAccessConditions: SequenceNumberAccessConditions{IfSequenceNumberLessThan: 10}}, nil, ClientProvidedKeyOptions{}) 623 c.Assert(err, chk.IsNil) 624 625 validateUploadPages(c, blobURL) 626} 627 628func (s *aztestsSuite) TestBlobPutPagesIfSequenceNumberLessThanFalse(c *chk.C) { 629 bsu := getBSU() 630 containerURL, _ := createNewContainer(c, bsu) 631 defer deleteContainer(c, containerURL) 632 blobURL, _ := createNewPageBlob(c, containerURL) 633 634 blobURL.UpdateSequenceNumber(ctx, SequenceNumberActionUpdate, 10, BlobAccessConditions{}) 635 _, err := blobURL.UploadPages(ctx, 0, getReaderToRandomBytes(PageBlobPageBytes), PageBlobAccessConditions{SequenceNumberAccessConditions: SequenceNumberAccessConditions{IfSequenceNumberLessThan: 1}}, nil, ClientProvidedKeyOptions{}) 636 validateStorageError(c, err, ServiceCodeSequenceNumberConditionNotMet) 637} 638 639func (s *aztestsSuite) TestBlobPutPagesIfSequenceNumberLessThanNegOne(c *chk.C) { 640 bsu := getBSU() 641 containerURL, _ := createNewContainer(c, bsu) 642 defer deleteContainer(c, containerURL) 643 blobURL, _ := createNewPageBlob(c, containerURL) 644 645 _, err := blobURL.UploadPages(ctx, 0, getReaderToRandomBytes(PageBlobPageBytes), PageBlobAccessConditions{SequenceNumberAccessConditions: SequenceNumberAccessConditions{IfSequenceNumberLessThan: -1}}, nil, ClientProvidedKeyOptions{}) // This will cause the library to set the value of the header to 0 646 validateStorageError(c, err, ServiceCodeSequenceNumberConditionNotMet) 647} 648 649func (s *aztestsSuite) TestBlobPutPagesIfSequenceNumberLTETrue(c *chk.C) { 650 bsu := getBSU() 651 containerURL, _ := createNewContainer(c, bsu) 652 defer deleteContainer(c, containerURL) 653 blobURL, _ := createNewPageBlob(c, containerURL) 654 655 blobURL.UpdateSequenceNumber(ctx, SequenceNumberActionUpdate, 1, BlobAccessConditions{}) 656 _, err := blobURL.UploadPages(ctx, 0, getReaderToRandomBytes(PageBlobPageBytes), PageBlobAccessConditions{SequenceNumberAccessConditions: SequenceNumberAccessConditions{IfSequenceNumberLessThanOrEqual: 1}}, nil, ClientProvidedKeyOptions{}) 657 c.Assert(err, chk.IsNil) 658 659 validateUploadPages(c, blobURL) 660} 661 662func (s *aztestsSuite) TestBlobPutPagesIfSequenceNumberLTEqualFalse(c *chk.C) { 663 bsu := getBSU() 664 containerURL, _ := createNewContainer(c, bsu) 665 defer deleteContainer(c, containerURL) 666 blobURL, _ := createNewPageBlob(c, containerURL) 667 668 blobURL.UpdateSequenceNumber(ctx, SequenceNumberActionUpdate, 10, BlobAccessConditions{}) 669 _, err := blobURL.UploadPages(ctx, 0, getReaderToRandomBytes(PageBlobPageBytes), PageBlobAccessConditions{SequenceNumberAccessConditions: SequenceNumberAccessConditions{IfSequenceNumberLessThanOrEqual: 1}}, nil, ClientProvidedKeyOptions{}) 670 validateStorageError(c, err, ServiceCodeSequenceNumberConditionNotMet) 671} 672 673func (s *aztestsSuite) TestBlobPutPagesIfSequenceNumberLTENegOne(c *chk.C) { 674 bsu := getBSU() 675 containerURL, _ := createNewContainer(c, bsu) 676 defer deleteContainer(c, containerURL) 677 blobURL, _ := createNewPageBlob(c, containerURL) 678 679 _, err := blobURL.UploadPages(ctx, 0, getReaderToRandomBytes(PageBlobPageBytes), PageBlobAccessConditions{SequenceNumberAccessConditions: SequenceNumberAccessConditions{IfSequenceNumberLessThanOrEqual: -1}}, nil, ClientProvidedKeyOptions{}) // This will cause the library to set the value of the header to 0 680 c.Assert(err, chk.IsNil) 681 682 validateUploadPages(c, blobURL) 683} 684 685func (s *aztestsSuite) TestBlobPutPagesIfSequenceNumberEqualTrue(c *chk.C) { 686 bsu := getBSU() 687 containerURL, _ := createNewContainer(c, bsu) 688 defer deleteContainer(c, containerURL) 689 blobURL, _ := createNewPageBlob(c, containerURL) 690 691 blobURL.UpdateSequenceNumber(ctx, SequenceNumberActionUpdate, 1, BlobAccessConditions{}) 692 _, err := blobURL.UploadPages(ctx, 0, getReaderToRandomBytes(PageBlobPageBytes), PageBlobAccessConditions{SequenceNumberAccessConditions: SequenceNumberAccessConditions{IfSequenceNumberEqual: 1}}, nil, ClientProvidedKeyOptions{}) 693 c.Assert(err, chk.IsNil) 694 695 validateUploadPages(c, blobURL) 696} 697 698func (s *aztestsSuite) TestBlobPutPagesIfSequenceNumberEqualFalse(c *chk.C) { 699 bsu := getBSU() 700 containerURL, _ := createNewContainer(c, bsu) 701 defer deleteContainer(c, containerURL) 702 blobURL, _ := createNewPageBlob(c, containerURL) 703 704 _, err := blobURL.UploadPages(ctx, 0, getReaderToRandomBytes(PageBlobPageBytes), PageBlobAccessConditions{SequenceNumberAccessConditions: SequenceNumberAccessConditions{IfSequenceNumberEqual: 1}}, nil, ClientProvidedKeyOptions{}) 705 validateStorageError(c, err, ServiceCodeSequenceNumberConditionNotMet) 706} 707 708func (s *aztestsSuite) TestBlobPutPagesIfSequenceNumberEqualNegOne(c *chk.C) { 709 bsu := getBSU() 710 containerURL, _ := createNewContainer(c, bsu) 711 defer deleteContainer(c, containerURL) 712 blobURL, _ := createNewPageBlob(c, containerURL) 713 714 _, err := blobURL.UploadPages(ctx, 0, getReaderToRandomBytes(PageBlobPageBytes), PageBlobAccessConditions{SequenceNumberAccessConditions: SequenceNumberAccessConditions{IfSequenceNumberEqual: -1}}, nil, ClientProvidedKeyOptions{}) // This will cause the library to set the value of the header to 0 715 c.Assert(err, chk.IsNil) 716 717 validateUploadPages(c, blobURL) 718} 719 720func setupClearPagesTest(c *chk.C) (ContainerURL, PageBlobURL) { 721 bsu := getBSU() 722 containerURL, _ := createNewContainer(c, bsu) 723 blobURL, _ := createNewPageBlob(c, containerURL) 724 725 _, err := blobURL.UploadPages(ctx, 0, getReaderToRandomBytes(PageBlobPageBytes), PageBlobAccessConditions{}, nil, ClientProvidedKeyOptions{}) 726 c.Assert(err, chk.IsNil) 727 728 return containerURL, blobURL 729} 730 731func validateClearPagesTest(c *chk.C, blobURL PageBlobURL) { 732 resp, err := blobURL.GetPageRanges(ctx, 0, 0, BlobAccessConditions{}) 733 c.Assert(err, chk.IsNil) 734 c.Assert(resp.PageRange, chk.HasLen, 0) 735} 736 737func (s *aztestsSuite) TestBlobClearPagesInvalidRange(c *chk.C) { 738 containerURL, blobURL := setupClearPagesTest(c) 739 defer deleteContainer(c, containerURL) 740 741 _, err := blobURL.ClearPages(ctx, 0, PageBlobPageBytes+1, PageBlobAccessConditions{}, ClientProvidedKeyOptions{}) 742 c.Assert(err, chk.Not(chk.IsNil)) 743} 744 745func (s *aztestsSuite) TestBlobClearPagesIfModifiedSinceTrue(c *chk.C) { 746 containerURL, blobURL := setupClearPagesTest(c) 747 defer deleteContainer(c, containerURL) 748 749 currentTime := getRelativeTimeGMT(-10) 750 751 _, err := blobURL.ClearPages(ctx, 0, PageBlobPageBytes, PageBlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}}, ClientProvidedKeyOptions{}) 752 c.Assert(err, chk.IsNil) 753 754 validateClearPagesTest(c, blobURL) 755} 756 757func (s *aztestsSuite) TestBlobClearPagesIfModifiedSinceFalse(c *chk.C) { 758 containerURL, blobURL := setupClearPagesTest(c) 759 defer deleteContainer(c, containerURL) 760 761 currentTime := getRelativeTimeGMT(10) 762 763 _, err := blobURL.ClearPages(ctx, 0, PageBlobPageBytes, PageBlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}}, ClientProvidedKeyOptions{}) 764 validateStorageError(c, err, ServiceCodeConditionNotMet) 765} 766 767func (s *aztestsSuite) TestBlobClearPagesIfUnmodifiedSinceTrue(c *chk.C) { 768 containerURL, blobURL := setupClearPagesTest(c) 769 defer deleteContainer(c, containerURL) 770 771 currentTime := getRelativeTimeGMT(10) 772 773 _, err := blobURL.ClearPages(ctx, 0, PageBlobPageBytes, PageBlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}}, ClientProvidedKeyOptions{}) 774 c.Assert(err, chk.IsNil) 775 776 validateClearPagesTest(c, blobURL) 777} 778 779func (s *aztestsSuite) TestBlobClearPagesIfUnmodifiedSinceFalse(c *chk.C) { 780 containerURL, blobURL := setupClearPagesTest(c) 781 defer deleteContainer(c, containerURL) 782 783 currentTime := getRelativeTimeGMT(-10) 784 785 _, err := blobURL.ClearPages(ctx, 0, PageBlobPageBytes, PageBlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}}, ClientProvidedKeyOptions{}) 786 validateStorageError(c, err, ServiceCodeConditionNotMet) 787} 788 789func (s *aztestsSuite) TestBlobClearPagesIfMatchTrue(c *chk.C) { 790 containerURL, blobURL := setupClearPagesTest(c) 791 defer deleteContainer(c, containerURL) 792 793 resp, _ := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{}) 794 795 _, err := blobURL.ClearPages(ctx, 0, PageBlobPageBytes, PageBlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: resp.ETag()}}, ClientProvidedKeyOptions{}) 796 c.Assert(err, chk.IsNil) 797 798 validateClearPagesTest(c, blobURL) 799} 800 801func (s *aztestsSuite) TestBlobClearPagesIfMatchFalse(c *chk.C) { 802 containerURL, blobURL := setupClearPagesTest(c) 803 defer deleteContainer(c, containerURL) 804 805 _, err := blobURL.ClearPages(ctx, 0, PageBlobPageBytes, PageBlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: ETag("garbage")}}, ClientProvidedKeyOptions{}) 806 validateStorageError(c, err, ServiceCodeConditionNotMet) 807} 808 809func (s *aztestsSuite) TestBlobClearPagesIfNoneMatchTrue(c *chk.C) { 810 containerURL, blobURL := setupClearPagesTest(c) 811 defer deleteContainer(c, containerURL) 812 813 _, err := blobURL.ClearPages(ctx, 0, PageBlobPageBytes, PageBlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfNoneMatch: ETag("garbage")}}, ClientProvidedKeyOptions{}) 814 c.Assert(err, chk.IsNil) 815 816 validateClearPagesTest(c, blobURL) 817} 818 819func (s *aztestsSuite) TestBlobClearPagesIfNoneMatchFalse(c *chk.C) { 820 containerURL, blobURL := setupClearPagesTest(c) 821 defer deleteContainer(c, containerURL) 822 823 resp, _ := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{}) 824 825 _, err := blobURL.ClearPages(ctx, 0, PageBlobPageBytes, PageBlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfNoneMatch: resp.ETag()}}, ClientProvidedKeyOptions{}) 826 validateStorageError(c, err, ServiceCodeConditionNotMet) 827} 828 829func (s *aztestsSuite) TestBlobClearPagesIfSequenceNumberLessThanTrue(c *chk.C) { 830 containerURL, blobURL := setupClearPagesTest(c) 831 defer deleteContainer(c, containerURL) 832 833 _, err := blobURL.ClearPages(ctx, 0, PageBlobPageBytes, PageBlobAccessConditions{SequenceNumberAccessConditions: SequenceNumberAccessConditions{IfSequenceNumberLessThan: 10}}, ClientProvidedKeyOptions{}) 834 c.Assert(err, chk.IsNil) 835 836 validateClearPagesTest(c, blobURL) 837} 838 839func (s *aztestsSuite) TestBlobClearPagesIfSequenceNumberLessThanFalse(c *chk.C) { 840 containerURL, blobURL := setupClearPagesTest(c) 841 defer deleteContainer(c, containerURL) 842 843 _, err := blobURL.UpdateSequenceNumber(ctx, SequenceNumberActionUpdate, 10, BlobAccessConditions{}) 844 c.Assert(err, chk.IsNil) 845 _, err = blobURL.ClearPages(ctx, 0, PageBlobPageBytes, PageBlobAccessConditions{SequenceNumberAccessConditions: SequenceNumberAccessConditions{IfSequenceNumberLessThan: 1}}, ClientProvidedKeyOptions{}) 846 validateStorageError(c, err, ServiceCodeSequenceNumberConditionNotMet) 847} 848 849func (s *aztestsSuite) TestBlobClearPagesIfSequenceNumberLessThanNegOne(c *chk.C) { 850 containerURL, blobURL := setupClearPagesTest(c) 851 defer deleteContainer(c, containerURL) 852 853 _, err := blobURL.ClearPages(ctx, 0, PageBlobPageBytes, PageBlobAccessConditions{SequenceNumberAccessConditions: SequenceNumberAccessConditions{IfSequenceNumberLessThan: -1}}, ClientProvidedKeyOptions{}) // This will cause the library to set the value of the header to 0 854 validateStorageError(c, err, ServiceCodeSequenceNumberConditionNotMet) 855} 856 857func (s *aztestsSuite) TestBlobClearPagesIfSequenceNumberLTETrue(c *chk.C) { 858 containerURL, blobURL := setupClearPagesTest(c) 859 defer deleteContainer(c, containerURL) 860 861 _, err := blobURL.ClearPages(ctx, 0, PageBlobPageBytes, PageBlobAccessConditions{SequenceNumberAccessConditions: SequenceNumberAccessConditions{IfSequenceNumberLessThanOrEqual: 10}}, ClientProvidedKeyOptions{}) 862 c.Assert(err, chk.IsNil) 863 864 validateClearPagesTest(c, blobURL) 865} 866 867func (s *aztestsSuite) TestBlobClearPagesIfSequenceNumberLTEFalse(c *chk.C) { 868 containerURL, blobURL := setupClearPagesTest(c) 869 defer deleteContainer(c, containerURL) 870 871 _, err := blobURL.UpdateSequenceNumber(ctx, SequenceNumberActionUpdate, 10, BlobAccessConditions{}) 872 c.Assert(err, chk.IsNil) 873 _, err = blobURL.ClearPages(ctx, 0, PageBlobPageBytes, PageBlobAccessConditions{SequenceNumberAccessConditions: SequenceNumberAccessConditions{IfSequenceNumberLessThanOrEqual: 1}}, ClientProvidedKeyOptions{}) 874 validateStorageError(c, err, ServiceCodeSequenceNumberConditionNotMet) 875} 876 877func (s *aztestsSuite) TestBlobClearPagesIfSequenceNumberLTENegOne(c *chk.C) { 878 containerURL, blobURL := setupClearPagesTest(c) 879 defer deleteContainer(c, containerURL) 880 881 _, err := blobURL.ClearPages(ctx, 0, PageBlobPageBytes, PageBlobAccessConditions{SequenceNumberAccessConditions: SequenceNumberAccessConditions{IfSequenceNumberLessThanOrEqual: -1}}, ClientProvidedKeyOptions{}) // This will cause the library to set the value of the header to 0 882 c.Assert(err, chk.IsNil) 883 884 validateClearPagesTest(c, blobURL) 885} 886 887func (s *aztestsSuite) TestBlobClearPagesIfSequenceNumberEqualTrue(c *chk.C) { 888 containerURL, blobURL := setupClearPagesTest(c) 889 defer deleteContainer(c, containerURL) 890 891 _, err := blobURL.UpdateSequenceNumber(ctx, SequenceNumberActionUpdate, 10, BlobAccessConditions{}) 892 c.Assert(err, chk.IsNil) 893 _, err = blobURL.ClearPages(ctx, 0, PageBlobPageBytes, PageBlobAccessConditions{SequenceNumberAccessConditions: SequenceNumberAccessConditions{IfSequenceNumberEqual: 10}}, ClientProvidedKeyOptions{}) 894 c.Assert(err, chk.IsNil) 895 896 validateClearPagesTest(c, blobURL) 897} 898 899func (s *aztestsSuite) TestBlobClearPagesIfSequenceNumberEqualFalse(c *chk.C) { 900 containerURL, blobURL := setupClearPagesTest(c) 901 defer deleteContainer(c, containerURL) 902 903 _, err := blobURL.UpdateSequenceNumber(ctx, SequenceNumberActionUpdate, 10, BlobAccessConditions{}) 904 c.Assert(err, chk.IsNil) 905 _, err = blobURL.ClearPages(ctx, 0, PageBlobPageBytes, PageBlobAccessConditions{SequenceNumberAccessConditions: SequenceNumberAccessConditions{IfSequenceNumberEqual: 1}}, ClientProvidedKeyOptions{}) 906 validateStorageError(c, err, ServiceCodeSequenceNumberConditionNotMet) 907} 908 909func (s *aztestsSuite) TestBlobClearPagesIfSequenceNumberEqualNegOne(c *chk.C) { 910 containerURL, blobURL := setupClearPagesTest(c) 911 defer deleteContainer(c, containerURL) 912 913 _, err := blobURL.ClearPages(ctx, 0, PageBlobPageBytes, PageBlobAccessConditions{SequenceNumberAccessConditions: SequenceNumberAccessConditions{IfSequenceNumberEqual: -1}}, ClientProvidedKeyOptions{}) // This will cause the library to set the value of the header to 0 914 c.Assert(err, chk.IsNil) 915 916 validateClearPagesTest(c, blobURL) 917} 918 919func setupGetPageRangesTest(c *chk.C) (containerURL ContainerURL, blobURL PageBlobURL) { 920 bsu := getBSU() 921 containerURL, _ = createNewContainer(c, bsu) 922 blobURL, _ = createNewPageBlob(c, containerURL) 923 924 _, err := blobURL.UploadPages(ctx, 0, getReaderToRandomBytes(PageBlobPageBytes), PageBlobAccessConditions{}, nil, ClientProvidedKeyOptions{}) 925 c.Assert(err, chk.IsNil) 926 927 return 928} 929 930func validateBasicGetPageRanges(c *chk.C, resp *PageList, err error) { 931 c.Assert(err, chk.IsNil) 932 c.Assert(resp.PageRange, chk.HasLen, 1) 933 c.Assert(resp.PageRange[0], chk.Equals, PageRange{Start: 0, End: PageBlobPageBytes - 1}) 934} 935 936func (s *aztestsSuite) TestBlobGetPageRangesEmptyBlob(c *chk.C) { 937 bsu := getBSU() 938 containerURL, _ := createNewContainer(c, bsu) 939 defer deleteContainer(c, containerURL) 940 blobURL, _ := createNewPageBlob(c, containerURL) 941 942 resp, err := blobURL.GetPageRanges(ctx, 0, 0, BlobAccessConditions{}) 943 c.Assert(err, chk.IsNil) 944 c.Assert(resp.PageRange, chk.HasLen, 0) 945} 946 947func (s *aztestsSuite) TestBlobGetPageRangesEmptyRange(c *chk.C) { 948 containerURL, blobURL := setupGetPageRangesTest(c) 949 defer deleteContainer(c, containerURL) 950 951 resp, err := blobURL.GetPageRanges(ctx, 0, 0, BlobAccessConditions{}) 952 validateBasicGetPageRanges(c, resp, err) 953} 954 955func (s *aztestsSuite) TestBlobGetPageRangesInvalidRange(c *chk.C) { 956 containerURL, blobURL := setupGetPageRangesTest(c) 957 defer deleteContainer(c, containerURL) 958 959 _, err := blobURL.GetPageRanges(ctx, -2, 500, BlobAccessConditions{}) 960 c.Assert(err, chk.IsNil) 961} 962 963func (s *aztestsSuite) TestBlobGetPageRangesNonContiguousRanges(c *chk.C) { 964 containerURL, blobURL := setupGetPageRangesTest(c) 965 defer deleteContainer(c, containerURL) 966 967 _, err := blobURL.UploadPages(ctx, PageBlobPageBytes*2, getReaderToRandomBytes(PageBlobPageBytes), PageBlobAccessConditions{}, nil, ClientProvidedKeyOptions{}) 968 c.Assert(err, chk.IsNil) 969 resp, err := blobURL.GetPageRanges(ctx, 0, 0, BlobAccessConditions{}) 970 c.Assert(err, chk.IsNil) 971 c.Assert(resp.PageRange, chk.HasLen, 2) 972 c.Assert(resp.PageRange[0], chk.Equals, PageRange{Start: 0, End: PageBlobPageBytes - 1}) 973 c.Assert(resp.PageRange[1], chk.Equals, PageRange{Start: PageBlobPageBytes * 2, End: (PageBlobPageBytes * 3) - 1}) 974} 975func (s *aztestsSuite) TestblobGetPageRangesNotPageAligned(c *chk.C) { 976 containerURL, blobURL := setupGetPageRangesTest(c) 977 defer deleteContainer(c, containerURL) 978 979 resp, err := blobURL.GetPageRanges(ctx, 0, 2000, BlobAccessConditions{}) 980 c.Assert(err, chk.IsNil) 981 validateBasicGetPageRanges(c, resp, err) 982} 983 984func (s *aztestsSuite) TestBlobGetPageRangesSnapshot(c *chk.C) { 985 containerURL, blobURL := setupGetPageRangesTest(c) 986 defer deleteContainer(c, containerURL) 987 988 resp, _ := blobURL.CreateSnapshot(ctx, nil, BlobAccessConditions{}, ClientProvidedKeyOptions{}) 989 snapshotURL := blobURL.WithSnapshot(resp.Snapshot()) 990 resp2, err := snapshotURL.GetPageRanges(ctx, 0, 0, BlobAccessConditions{}) 991 c.Assert(err, chk.IsNil) 992 validateBasicGetPageRanges(c, resp2, err) 993} 994 995func (s *aztestsSuite) TestBlobGetPageRangesIfModifiedSinceTrue(c *chk.C) { 996 containerURL, blobURL := setupGetPageRangesTest(c) 997 defer deleteContainer(c, containerURL) 998 999 currentTime := getRelativeTimeGMT(-10) 1000 1001 resp, err := blobURL.GetPageRanges(ctx, 0, 0, 1002 BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}}) 1003 validateBasicGetPageRanges(c, resp, err) 1004} 1005 1006func (s *aztestsSuite) TestBlobGetPageRangesIfModifiedSinceFalse(c *chk.C) { 1007 containerURL, blobURL := setupGetPageRangesTest(c) 1008 defer deleteContainer(c, containerURL) 1009 1010 currentTime := getRelativeTimeGMT(10) 1011 1012 _, err := blobURL.GetPageRanges(ctx, 0, 0, 1013 BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}}) 1014 serr := err.(StorageError) 1015 c.Assert(serr.Response().StatusCode, chk.Equals, 304) // Service Code not returned in the body for a HEAD 1016} 1017 1018func (s *aztestsSuite) TestBlobGetPageRangesIfUnmodifiedSinceTrue(c *chk.C) { 1019 containerURL, blobURL := setupGetPageRangesTest(c) 1020 defer deleteContainer(c, containerURL) 1021 1022 currentTime := getRelativeTimeGMT(10) 1023 1024 resp, err := blobURL.GetPageRanges(ctx, 0, 0, 1025 BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}}) 1026 validateBasicGetPageRanges(c, resp, err) 1027} 1028 1029func (s *aztestsSuite) TestBlobGetPageRangesIfUnmodifiedSinceFalse(c *chk.C) { 1030 containerURL, blobURL := setupGetPageRangesTest(c) 1031 defer deleteContainer(c, containerURL) 1032 1033 currentTime := getRelativeTimeGMT(-10) 1034 1035 _, err := blobURL.GetPageRanges(ctx, 0, 0, 1036 BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}}) 1037 validateStorageError(c, err, ServiceCodeConditionNotMet) 1038} 1039 1040func (s *aztestsSuite) TestBlobGetPageRangesIfMatchTrue(c *chk.C) { 1041 containerURL, blobURL := setupGetPageRangesTest(c) 1042 defer deleteContainer(c, containerURL) 1043 1044 resp, _ := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{}) 1045 1046 resp2, err := blobURL.GetPageRanges(ctx, 0, 0, 1047 BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: resp.ETag()}}) 1048 validateBasicGetPageRanges(c, resp2, err) 1049} 1050 1051func (s *aztestsSuite) TestBlobGetPageRangesIfMatchFalse(c *chk.C) { 1052 containerURL, blobURL := setupGetPageRangesTest(c) 1053 defer deleteContainer(c, containerURL) 1054 1055 _, err := blobURL.GetPageRanges(ctx, 0, 0, 1056 BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: ETag("garbage")}}) 1057 validateStorageError(c, err, ServiceCodeConditionNotMet) 1058} 1059 1060func (s *aztestsSuite) TestBlobGetPageRangesIfNoneMatchTrue(c *chk.C) { 1061 containerURL, blobURL := setupGetPageRangesTest(c) 1062 defer deleteContainer(c, containerURL) 1063 1064 resp, err := blobURL.GetPageRanges(ctx, 0, 0, 1065 BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfNoneMatch: ETag("garbage")}}) 1066 validateBasicGetPageRanges(c, resp, err) 1067} 1068 1069func (s *aztestsSuite) TestBlobGetPageRangesIfNoneMatchFalse(c *chk.C) { 1070 containerURL, blobURL := setupGetPageRangesTest(c) 1071 defer deleteContainer(c, containerURL) 1072 1073 resp, _ := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{}) 1074 1075 _, err := blobURL.GetPageRanges(ctx, 0, 0, 1076 BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfNoneMatch: resp.ETag()}}) 1077 serr := err.(StorageError) 1078 c.Assert(serr.Response().StatusCode, chk.Equals, 304) // Service Code not returned in the body for a HEAD 1079} 1080 1081func setupDiffPageRangesTest(c *chk.C) (containerURL ContainerURL, blobURL PageBlobURL, snapshot string) { 1082 bsu := getBSU() 1083 containerURL, _ = createNewContainer(c, bsu) 1084 blobURL, _ = createNewPageBlob(c, containerURL) 1085 1086 _, err := blobURL.UploadPages(ctx, 0, getReaderToRandomBytes(PageBlobPageBytes), PageBlobAccessConditions{}, nil, ClientProvidedKeyOptions{}) 1087 c.Assert(err, chk.IsNil) 1088 1089 resp, err := blobURL.CreateSnapshot(ctx, nil, BlobAccessConditions{}, ClientProvidedKeyOptions{}) 1090 c.Assert(err, chk.IsNil) 1091 snapshot = resp.Snapshot() 1092 1093 _, err = blobURL.UploadPages(ctx, 0, getReaderToRandomBytes(PageBlobPageBytes), PageBlobAccessConditions{}, nil, ClientProvidedKeyOptions{}) 1094 c.Assert(err, chk.IsNil) // This ensures there is a diff on the first page 1095 return 1096} 1097 1098func validateDiffPageRanges(c *chk.C, resp *PageList, err error) { 1099 c.Assert(err, chk.IsNil) 1100 c.Assert(resp.PageRange, chk.HasLen, 1) 1101 c.Assert(resp.PageRange[0].Start, chk.Equals, int64(0)) 1102 c.Assert(resp.PageRange[0].End, chk.Equals, int64(PageBlobPageBytes-1)) 1103} 1104 1105func (s *aztestsSuite) TestBlobDiffPageRangesNonExistantSnapshot(c *chk.C) { 1106 containerURL, blobURL, snapshot := setupDiffPageRangesTest(c) 1107 defer deleteContainer(c, containerURL) 1108 1109 snapshotTime, _ := time.Parse(SnapshotTimeFormat, snapshot) 1110 snapshotTime = snapshotTime.Add(time.Minute) 1111 _, err := blobURL.GetPageRangesDiff(ctx, 0, 0, snapshotTime.Format(SnapshotTimeFormat), BlobAccessConditions{}) 1112 validateStorageError(c, err, ServiceCodePreviousSnapshotNotFound) 1113} 1114 1115func (s *aztestsSuite) TestBlobDiffPageRangeInvalidRange(c *chk.C) { 1116 containerURL, blobURL, snapshot := setupDiffPageRangesTest(c) 1117 defer deleteContainer(c, containerURL) 1118 _, err := blobURL.GetPageRangesDiff(ctx, -22, 14, snapshot, BlobAccessConditions{}) 1119 c.Assert(err, chk.IsNil) 1120} 1121 1122func (s *aztestsSuite) TestBlobDiffPageRangeIfModifiedSinceTrue(c *chk.C) { 1123 containerURL, blobURL, snapshot := setupDiffPageRangesTest(c) 1124 defer deleteContainer(c, containerURL) 1125 1126 currentTime := getRelativeTimeGMT(-10) 1127 1128 resp, err := blobURL.GetPageRangesDiff(ctx, 0, 0, snapshot, 1129 BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}}) 1130 validateDiffPageRanges(c, resp, err) 1131} 1132 1133func (s *aztestsSuite) TestBlobDiffPageRangeIfModifiedSinceFalse(c *chk.C) { 1134 containerURL, blobURL, snapshot := setupDiffPageRangesTest(c) 1135 defer deleteContainer(c, containerURL) 1136 1137 currentTime := getRelativeTimeGMT(10) 1138 1139 _, err := blobURL.GetPageRangesDiff(ctx, 0, 0, snapshot, 1140 BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}}) 1141 serr := err.(StorageError) 1142 c.Assert(serr.Response().StatusCode, chk.Equals, 304) // Service Code not returned in the body for a HEAD 1143} 1144 1145func (s *aztestsSuite) TestBlobDiffPageRangeIfUnmodifiedSinceTrue(c *chk.C) { 1146 containerURL, blobURL, snapshot := setupDiffPageRangesTest(c) 1147 defer deleteContainer(c, containerURL) 1148 1149 currentTime := getRelativeTimeGMT(10) 1150 1151 resp, err := blobURL.GetPageRangesDiff(ctx, 0, 0, snapshot, 1152 BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}}) 1153 validateDiffPageRanges(c, resp, err) 1154} 1155 1156func (s *aztestsSuite) TestBlobDiffPageRangeIfUnmodifiedSinceFalse(c *chk.C) { 1157 containerURL, blobURL, snapshot := setupDiffPageRangesTest(c) 1158 defer deleteContainer(c, containerURL) 1159 1160 currentTime := getRelativeTimeGMT(-10) 1161 1162 _, err := blobURL.GetPageRangesDiff(ctx, 0, 0, snapshot, 1163 BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}}) 1164 validateStorageError(c, err, ServiceCodeConditionNotMet) 1165} 1166 1167func (s *aztestsSuite) TestBlobDiffPageRangeIfMatchTrue(c *chk.C) { 1168 containerURL, blobURL, snapshot := setupDiffPageRangesTest(c) 1169 defer deleteContainer(c, containerURL) 1170 1171 resp, _ := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{}) 1172 1173 resp2, err := blobURL.GetPageRangesDiff(ctx, 0, 0, snapshot, 1174 BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: resp.ETag()}}) 1175 validateDiffPageRanges(c, resp2, err) 1176} 1177 1178func (s *aztestsSuite) TestBlobDiffPageRangeIfMatchFalse(c *chk.C) { 1179 containerURL, blobURL, snapshot := setupDiffPageRangesTest(c) 1180 defer deleteContainer(c, containerURL) 1181 1182 _, err := blobURL.GetPageRangesDiff(ctx, 0, 0, snapshot, 1183 BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: ETag("garbage")}}) 1184 validateStorageError(c, err, ServiceCodeConditionNotMet) 1185} 1186 1187func (s *aztestsSuite) TestBlobDiffPageRangeIfNoneMatchTrue(c *chk.C) { 1188 containerURL, blobURL, snapshot := setupDiffPageRangesTest(c) 1189 defer deleteContainer(c, containerURL) 1190 1191 resp, err := blobURL.GetPageRangesDiff(ctx, 0, 0, snapshot, 1192 BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfNoneMatch: ETag("garbage")}}) 1193 validateDiffPageRanges(c, resp, err) 1194} 1195 1196func (s *aztestsSuite) TestBlobDiffPageRangeIfNoneMatchFalse(c *chk.C) { 1197 containerURL, blobURL, snapshot := setupDiffPageRangesTest(c) 1198 defer deleteContainer(c, containerURL) 1199 1200 resp, _ := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{}) 1201 1202 _, err := blobURL.GetPageRangesDiff(ctx, 0, 0, snapshot, 1203 BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfNoneMatch: resp.ETag()}}) 1204 serr := err.(StorageError) 1205 c.Assert(serr.Response().StatusCode, chk.Equals, 304) // Service Code not returned in the body for a HEAD 1206} 1207 1208func (s *aztestsSuite) TestBlobResizeZero(c *chk.C) { 1209 bsu := getBSU() 1210 containerURL, _ := createNewContainer(c, bsu) 1211 defer deleteContainer(c, containerURL) 1212 blobURL, _ := createNewPageBlob(c, containerURL) 1213 1214 // The default blob is created with size > 0, so this should actually update 1215 _, err := blobURL.Resize(ctx, 0, BlobAccessConditions{}, ClientProvidedKeyOptions{}) 1216 c.Assert(err, chk.IsNil) 1217 1218 resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{}) 1219 c.Assert(err, chk.IsNil) 1220 c.Assert(resp.ContentLength(), chk.Equals, int64(0)) 1221} 1222 1223func (s *aztestsSuite) TestBlobResizeInvalidSizeNegative(c *chk.C) { 1224 bsu := getBSU() 1225 containerURL, _ := createNewContainer(c, bsu) 1226 defer deleteContainer(c, containerURL) 1227 blobURL, _ := createNewPageBlob(c, containerURL) 1228 1229 _, err := blobURL.Resize(ctx, -4, BlobAccessConditions{}, ClientProvidedKeyOptions{}) 1230 c.Assert(err, chk.Not(chk.IsNil)) 1231} 1232 1233func (s *aztestsSuite) TestBlobResizeInvalidSizeMisaligned(c *chk.C) { 1234 bsu := getBSU() 1235 containerURL, _ := createNewContainer(c, bsu) 1236 defer deleteContainer(c, containerURL) 1237 blobURL, _ := createNewPageBlob(c, containerURL) 1238 1239 _, err := blobURL.Resize(ctx, 12, BlobAccessConditions{}, ClientProvidedKeyOptions{}) 1240 c.Assert(err, chk.Not(chk.IsNil)) 1241} 1242 1243func validateResize(c *chk.C, blobURL PageBlobURL) { 1244 resp, _ := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{}) 1245 c.Assert(resp.ContentLength(), chk.Equals, int64(PageBlobPageBytes)) 1246} 1247 1248func (s *aztestsSuite) TestBlobResizeIfModifiedSinceTrue(c *chk.C) { 1249 bsu := getBSU() 1250 containerURL, _ := createNewContainer(c, bsu) 1251 defer deleteContainer(c, containerURL) 1252 blobURL, _ := createNewPageBlob(c, containerURL) 1253 1254 currentTime := getRelativeTimeGMT(-10) 1255 1256 _, err := blobURL.Resize(ctx, PageBlobPageBytes, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}}, ClientProvidedKeyOptions{}) 1257 c.Assert(err, chk.IsNil) 1258 1259 validateResize(c, blobURL) 1260} 1261 1262func (s *aztestsSuite) TestBlobResizeIfModifiedSinceFalse(c *chk.C) { 1263 bsu := getBSU() 1264 containerURL, _ := createNewContainer(c, bsu) 1265 defer deleteContainer(c, containerURL) 1266 blobURL, _ := createNewPageBlob(c, containerURL) 1267 1268 currentTime := getRelativeTimeGMT(10) 1269 1270 _, err := blobURL.Resize(ctx, PageBlobPageBytes, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}}, ClientProvidedKeyOptions{}) 1271 validateStorageError(c, err, ServiceCodeConditionNotMet) 1272} 1273 1274func (s *aztestsSuite) TestBlobResizeIfUnmodifiedSinceTrue(c *chk.C) { 1275 bsu := getBSU() 1276 containerURL, _ := createNewContainer(c, bsu) 1277 defer deleteContainer(c, containerURL) 1278 blobURL, _ := createNewPageBlob(c, containerURL) 1279 1280 currentTime := getRelativeTimeGMT(10) 1281 1282 _, err := blobURL.Resize(ctx, PageBlobPageBytes, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}}, ClientProvidedKeyOptions{}) 1283 c.Assert(err, chk.IsNil) 1284 1285 validateResize(c, blobURL) 1286} 1287 1288func (s *aztestsSuite) TestBlobResizeIfUnmodifiedSinceFalse(c *chk.C) { 1289 bsu := getBSU() 1290 containerURL, _ := createNewContainer(c, bsu) 1291 defer deleteContainer(c, containerURL) 1292 blobURL, _ := createNewPageBlob(c, containerURL) 1293 1294 currentTime := getRelativeTimeGMT(-10) 1295 1296 _, err := blobURL.Resize(ctx, PageBlobPageBytes, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}}, ClientProvidedKeyOptions{}) 1297 validateStorageError(c, err, ServiceCodeConditionNotMet) 1298} 1299 1300func (s *aztestsSuite) TestBlobResizeIfMatchTrue(c *chk.C) { 1301 bsu := getBSU() 1302 containerURL, _ := createNewContainer(c, bsu) 1303 defer deleteContainer(c, containerURL) 1304 blobURL, _ := createNewPageBlob(c, containerURL) 1305 1306 resp, _ := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{}) 1307 1308 _, err := blobURL.Resize(ctx, PageBlobPageBytes, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: resp.ETag()}}, ClientProvidedKeyOptions{}) 1309 c.Assert(err, chk.IsNil) 1310 1311 validateResize(c, blobURL) 1312} 1313 1314func (s *aztestsSuite) TestBlobResizeIfMatchFalse(c *chk.C) { 1315 bsu := getBSU() 1316 containerURL, _ := createNewContainer(c, bsu) 1317 defer deleteContainer(c, containerURL) 1318 blobURL, _ := createNewPageBlob(c, containerURL) 1319 1320 _, err := blobURL.Resize(ctx, PageBlobPageBytes, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: ETag("garbage")}}, ClientProvidedKeyOptions{}) 1321 validateStorageError(c, err, ServiceCodeConditionNotMet) 1322} 1323 1324func (s *aztestsSuite) TestBlobResizeIfNoneMatchTrue(c *chk.C) { 1325 bsu := getBSU() 1326 containerURL, _ := createNewContainer(c, bsu) 1327 defer deleteContainer(c, containerURL) 1328 blobURL, _ := createNewPageBlob(c, containerURL) 1329 1330 _, err := blobURL.Resize(ctx, PageBlobPageBytes, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfNoneMatch: ETag("garbage")}}, ClientProvidedKeyOptions{}) 1331 c.Assert(err, chk.IsNil) 1332 1333 validateResize(c, blobURL) 1334} 1335 1336func (s *aztestsSuite) TestBlobResizeIfNoneMatchFalse(c *chk.C) { 1337 bsu := getBSU() 1338 containerURL, _ := createNewContainer(c, bsu) 1339 defer deleteContainer(c, containerURL) 1340 blobURL, _ := createNewPageBlob(c, containerURL) 1341 1342 resp, _ := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{}) 1343 1344 _, err := blobURL.Resize(ctx, PageBlobPageBytes, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfNoneMatch: resp.ETag()}}, ClientProvidedKeyOptions{}) 1345 validateStorageError(c, err, ServiceCodeConditionNotMet) 1346} 1347 1348func (s *aztestsSuite) TestBlobSetSequenceNumberActionTypeInvalid(c *chk.C) { 1349 bsu := getBSU() 1350 containerURL, _ := createNewContainer(c, bsu) 1351 defer deleteContainer(c, containerURL) 1352 blobURL, _ := createNewPageBlob(c, containerURL) 1353 1354 _, err := blobURL.UpdateSequenceNumber(ctx, SequenceNumberActionType("garbage"), 1, BlobAccessConditions{}) 1355 validateStorageError(c, err, ServiceCodeInvalidHeaderValue) 1356} 1357 1358func (s *aztestsSuite) TestBlobSetSequenceNumberSequenceNumberInvalid(c *chk.C) { 1359 bsu := getBSU() 1360 containerURL, _ := createNewContainer(c, bsu) 1361 defer deleteContainer(c, containerURL) 1362 blobURL, _ := createNewPageBlob(c, containerURL) 1363 1364 defer func() { // Invalid sequence number should panic 1365 recover() 1366 }() 1367 1368 blobURL.UpdateSequenceNumber(ctx, SequenceNumberActionUpdate, -1, BlobAccessConditions{}) 1369} 1370 1371func validateSequenceNumberSet(c *chk.C, blobURL PageBlobURL) { 1372 resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{}) 1373 c.Assert(err, chk.IsNil) 1374 c.Assert(resp.BlobSequenceNumber(), chk.Equals, int64(1)) 1375} 1376 1377func (s *aztestsSuite) TestBlobSetSequenceNumberIfModifiedSinceTrue(c *chk.C) { 1378 bsu := getBSU() 1379 containerURL, _ := createNewContainer(c, bsu) 1380 defer deleteContainer(c, containerURL) 1381 blobURL, _ := createNewPageBlob(c, containerURL) 1382 1383 currentTime := getRelativeTimeGMT(-10) 1384 1385 _, err := blobURL.UpdateSequenceNumber(ctx, SequenceNumberActionIncrement, 0, 1386 BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}}) 1387 c.Assert(err, chk.IsNil) 1388 1389 validateSequenceNumberSet(c, blobURL) 1390} 1391 1392func (s *aztestsSuite) TestBlobSetSequenceNumberIfModifiedSinceFalse(c *chk.C) { 1393 bsu := getBSU() 1394 containerURL, _ := createNewContainer(c, bsu) 1395 defer deleteContainer(c, containerURL) 1396 blobURL, _ := createNewPageBlob(c, containerURL) 1397 1398 currentTime := getRelativeTimeGMT(10) 1399 1400 _, err := blobURL.UpdateSequenceNumber(ctx, SequenceNumberActionIncrement, 0, 1401 BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}}) 1402 validateStorageError(c, err, ServiceCodeConditionNotMet) 1403} 1404 1405func (s *aztestsSuite) TestBlobSetSequenceNumberIfUnmodifiedSinceTrue(c *chk.C) { 1406 bsu := getBSU() 1407 containerURL, _ := createNewContainer(c, bsu) 1408 defer deleteContainer(c, containerURL) 1409 blobURL, _ := createNewPageBlob(c, containerURL) 1410 1411 currentTime := getRelativeTimeGMT(10) 1412 1413 _, err := blobURL.UpdateSequenceNumber(ctx, SequenceNumberActionIncrement, 0, 1414 BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}}) 1415 c.Assert(err, chk.IsNil) 1416 1417 validateSequenceNumberSet(c, blobURL) 1418} 1419 1420func (s *aztestsSuite) TestBlobSetSequenceNumberIfUnmodifiedSinceFalse(c *chk.C) { 1421 bsu := getBSU() 1422 containerURL, _ := createNewContainer(c, bsu) 1423 defer deleteContainer(c, containerURL) 1424 blobURL, _ := createNewPageBlob(c, containerURL) 1425 1426 currentTime := getRelativeTimeGMT(-10) 1427 1428 _, err := blobURL.UpdateSequenceNumber(ctx, SequenceNumberActionIncrement, 0, 1429 BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}}) 1430 validateStorageError(c, err, ServiceCodeConditionNotMet) 1431} 1432 1433func (s *aztestsSuite) TestBlobSetSequenceNumberIfMatchTrue(c *chk.C) { 1434 bsu := getBSU() 1435 containerURL, _ := createNewContainer(c, bsu) 1436 defer deleteContainer(c, containerURL) 1437 blobURL, _ := createNewPageBlob(c, containerURL) 1438 1439 resp, _ := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{}) 1440 1441 _, err := blobURL.UpdateSequenceNumber(ctx, SequenceNumberActionIncrement, 0, 1442 BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: resp.ETag()}}) 1443 c.Assert(err, chk.IsNil) 1444 1445 validateSequenceNumberSet(c, blobURL) 1446} 1447 1448func (s *aztestsSuite) TestBlobSetSequenceNumberIfMatchFalse(c *chk.C) { 1449 bsu := getBSU() 1450 containerURL, _ := createNewContainer(c, bsu) 1451 defer deleteContainer(c, containerURL) 1452 blobURL, _ := createNewPageBlob(c, containerURL) 1453 1454 _, err := blobURL.UpdateSequenceNumber(ctx, SequenceNumberActionIncrement, 0, 1455 BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: ETag("garbage")}}) 1456 validateStorageError(c, err, ServiceCodeConditionNotMet) 1457} 1458 1459func (s *aztestsSuite) TestBlobSetSequenceNumberIfNoneMatchTrue(c *chk.C) { 1460 bsu := getBSU() 1461 containerURL, _ := createNewContainer(c, bsu) 1462 defer deleteContainer(c, containerURL) 1463 blobURL, _ := createNewPageBlob(c, containerURL) 1464 1465 _, err := blobURL.UpdateSequenceNumber(ctx, SequenceNumberActionIncrement, 0, 1466 BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfNoneMatch: ETag("garbage")}}) 1467 c.Assert(err, chk.IsNil) 1468 1469 validateSequenceNumberSet(c, blobURL) 1470} 1471 1472func (s *aztestsSuite) TestBlobSetSequenceNumberIfNoneMatchFalse(c *chk.C) { 1473 bsu := getBSU() 1474 containerURL, _ := createNewContainer(c, bsu) 1475 defer deleteContainer(c, containerURL) 1476 blobURL, _ := createNewPageBlob(c, containerURL) 1477 1478 resp, _ := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{}) 1479 1480 _, err := blobURL.UpdateSequenceNumber(ctx, SequenceNumberActionIncrement, 0, 1481 BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfNoneMatch: resp.ETag()}}) 1482 validateStorageError(c, err, ServiceCodeConditionNotMet) 1483} 1484 1485func waitForIncrementalCopy(c *chk.C, copyBlobURL PageBlobURL, blobCopyResponse *PageBlobCopyIncrementalResponse) string { 1486 status := blobCopyResponse.CopyStatus() 1487 var getPropertiesAndMetadataResult *BlobGetPropertiesResponse 1488 // Wait for the copy to finish 1489 start := time.Now() 1490 for status != CopyStatusSuccess { 1491 getPropertiesAndMetadataResult, _ = copyBlobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{}) 1492 status = getPropertiesAndMetadataResult.CopyStatus() 1493 currentTime := time.Now() 1494 if currentTime.Sub(start) >= time.Minute { 1495 c.Fail() 1496 } 1497 } 1498 return getPropertiesAndMetadataResult.DestinationSnapshot() 1499} 1500 1501func setupStartIncrementalCopyTest(c *chk.C) (containerURL ContainerURL, blobURL PageBlobURL, copyBlobURL PageBlobURL, snapshot string) { 1502 bsu := getBSU() 1503 containerURL, _ = createNewContainer(c, bsu) 1504 containerURL.SetAccessPolicy(ctx, PublicAccessBlob, nil, ContainerAccessConditions{}) 1505 blobURL, _ = createNewPageBlob(c, containerURL) 1506 resp, _ := blobURL.CreateSnapshot(ctx, nil, BlobAccessConditions{}, ClientProvidedKeyOptions{}) 1507 copyBlobURL, _ = getPageBlobURL(c, containerURL) 1508 1509 // Must create the incremental copy blob so that the access conditions work on it 1510 resp2, err := copyBlobURL.StartCopyIncremental(ctx, blobURL.URL(), resp.Snapshot(), BlobAccessConditions{}) 1511 c.Assert(err, chk.IsNil) 1512 waitForIncrementalCopy(c, copyBlobURL, resp2) 1513 1514 resp, _ = blobURL.CreateSnapshot(ctx, nil, BlobAccessConditions{}, ClientProvidedKeyOptions{}) // Take a new snapshot so the next copy will succeed 1515 snapshot = resp.Snapshot() 1516 return 1517} 1518 1519func validateIncrementalCopy(c *chk.C, copyBlobURL PageBlobURL, resp *PageBlobCopyIncrementalResponse) { 1520 t := waitForIncrementalCopy(c, copyBlobURL, resp) 1521 1522 // If we can access the snapshot without error, we are satisfied that it was created as a result of the copy 1523 copySnapshotURL := copyBlobURL.WithSnapshot(t) 1524 _, err := copySnapshotURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{}) 1525 c.Assert(err, chk.IsNil) 1526} 1527 1528func (s *aztestsSuite) TestBlobStartIncrementalCopySnapshotNotExist(c *chk.C) { 1529 bsu := getBSU() 1530 containerURL, _ := createNewContainer(c, bsu) 1531 defer deleteContainer(c, containerURL) 1532 blobURL, _ := createNewPageBlob(c, containerURL) 1533 copyBlobURL, _ := getPageBlobURL(c, containerURL) 1534 1535 snapshot := time.Now().UTC().Format(SnapshotTimeFormat) 1536 _, err := copyBlobURL.StartCopyIncremental(ctx, blobURL.URL(), snapshot, BlobAccessConditions{}) 1537 validateStorageError(c, err, ServiceCodeCannotVerifyCopySource) 1538} 1539 1540func (s *aztestsSuite) TestBlobStartIncrementalCopyIfModifiedSinceTrue(c *chk.C) { 1541 containerURL, blobURL, copyBlobURL, snapshot := setupStartIncrementalCopyTest(c) 1542 1543 defer deleteContainer(c, containerURL) 1544 1545 currentTime := getRelativeTimeGMT(-20) 1546 1547 resp, err := copyBlobURL.StartCopyIncremental(ctx, blobURL.URL(), snapshot, 1548 BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}}) 1549 c.Assert(err, chk.IsNil) 1550 1551 validateIncrementalCopy(c, copyBlobURL, resp) 1552} 1553 1554func (s *aztestsSuite) TestBlobStartIncrementalCopyIfModifiedSinceFalse(c *chk.C) { 1555 containerURL, blobURL, copyBlobURL, snapshot := setupStartIncrementalCopyTest(c) 1556 1557 defer deleteContainer(c, containerURL) 1558 1559 currentTime := getRelativeTimeGMT(20) 1560 1561 _, err := copyBlobURL.StartCopyIncremental(ctx, blobURL.URL(), snapshot, 1562 BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}}) 1563 validateStorageError(c, err, ServiceCodeConditionNotMet) 1564} 1565 1566func (s *aztestsSuite) TestBlobStartIncrementalCopyIfUnmodifiedSinceTrue(c *chk.C) { 1567 containerURL, blobURL, copyBlobURL, snapshot := setupStartIncrementalCopyTest(c) 1568 1569 defer deleteContainer(c, containerURL) 1570 1571 currentTime := getRelativeTimeGMT(20) 1572 1573 resp, err := copyBlobURL.StartCopyIncremental(ctx, blobURL.URL(), snapshot, 1574 BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}}) 1575 c.Assert(err, chk.IsNil) 1576 1577 validateIncrementalCopy(c, copyBlobURL, resp) 1578} 1579 1580func (s *aztestsSuite) TestBlobStartIncrementalCopyIfUnmodifiedSinceFalse(c *chk.C) { 1581 containerURL, blobURL, copyBlobURL, snapshot := setupStartIncrementalCopyTest(c) 1582 1583 defer deleteContainer(c, containerURL) 1584 1585 currentTime := getRelativeTimeGMT(-20) 1586 1587 _, err := copyBlobURL.StartCopyIncremental(ctx, blobURL.URL(), snapshot, 1588 BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}}) 1589 validateStorageError(c, err, ServiceCodeConditionNotMet) 1590} 1591 1592func (s *aztestsSuite) TestBlobStartIncrementalCopyIfMatchTrue(c *chk.C) { 1593 containerURL, blobURL, copyBlobURL, snapshot := setupStartIncrementalCopyTest(c) 1594 1595 defer deleteContainer(c, containerURL) 1596 1597 resp, _ := copyBlobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{}) 1598 1599 resp2, err := copyBlobURL.StartCopyIncremental(ctx, blobURL.URL(), snapshot, 1600 BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: resp.ETag()}}) 1601 c.Assert(err, chk.IsNil) 1602 1603 validateIncrementalCopy(c, copyBlobURL, resp2) 1604} 1605 1606func (s *aztestsSuite) TestBlobStartIncrementalCopyIfMatchFalse(c *chk.C) { 1607 containerURL, blobURL, copyBlobURL, snapshot := setupStartIncrementalCopyTest(c) 1608 1609 defer deleteContainer(c, containerURL) 1610 1611 _, err := copyBlobURL.StartCopyIncremental(ctx, blobURL.URL(), snapshot, 1612 BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: ETag("garbage")}}) 1613 validateStorageError(c, err, ServiceCodeTargetConditionNotMet) 1614} 1615 1616func (s *aztestsSuite) TestBlobStartIncrementalCopyIfNoneMatchTrue(c *chk.C) { 1617 containerURL, blobURL, copyBlobURL, snapshot := setupStartIncrementalCopyTest(c) 1618 1619 defer deleteContainer(c, containerURL) 1620 1621 resp, err := copyBlobURL.StartCopyIncremental(ctx, blobURL.URL(), snapshot, 1622 BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfNoneMatch: ETag("garbage")}}) 1623 c.Assert(err, chk.IsNil) 1624 1625 validateIncrementalCopy(c, copyBlobURL, resp) 1626} 1627 1628func (s *aztestsSuite) TestBlobStartIncrementalCopyIfNoneMatchFalse(c *chk.C) { 1629 containerURL, blobURL, copyBlobURL, snapshot := setupStartIncrementalCopyTest(c) 1630 1631 defer deleteContainer(c, containerURL) 1632 1633 resp, _ := copyBlobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{}) 1634 1635 _, err := copyBlobURL.StartCopyIncremental(ctx, blobURL.URL(), snapshot, 1636 BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfNoneMatch: resp.ETag()}}) 1637 validateStorageError(c, err, ServiceCodeConditionNotMet) 1638} 1639