azure-storage-blob-go/azblob/zt_url_blob_test.go

1910 строки
76 KiB
Go

package azblob
import (
"crypto/md5"
"io"
"io/ioutil"
"bytes"
"errors"
"net/url"
"os"
"strings"
"time"
chk "gopkg.in/check.v1" // go get gopkg.in/check.v1
)
func (s *aztestsSuite) TestCreateBlobURL(c *chk.C) {
bsu := getBSU()
containerURL, containerName := getContainerURL(c, bsu)
testURL, testName := getBlockBlobURL(c, containerURL)
parts := NewBlobURLParts(testURL.URL())
c.Assert(parts.BlobName, chk.Equals, testName)
c.Assert(parts.ContainerName, chk.Equals, containerName)
correctURL := "https://" + os.Getenv("ACCOUNT_NAME") + ".blob.core.windows.net/" + containerName + "/" + testName
temp := testURL.URL()
c.Assert(temp.String(), chk.Equals, correctURL)
}
func (s *aztestsSuite) TestCreateBlobURLWithSnapshotAndSAS(c *chk.C) {
bsu := getBSU()
containerURL, containerName := getContainerURL(c, bsu)
blobURL, blobName := getBlockBlobURL(c, containerURL)
currentTime := time.Now().UTC()
credential, err := getGenericCredential("")
if err != nil {
c.Fatal("Invalid credential")
}
sasQueryParams, err := AccountSASSignatureValues{
Protocol: SASProtocolHTTPS,
ExpiryTime: currentTime.Add(48 * time.Hour),
Permissions: AccountSASPermissions{Read: true, List: true}.String(),
Services: AccountSASServices{Blob: true}.String(),
ResourceTypes: AccountSASResourceTypes{Container: true, Object: true}.String(),
}.NewSASQueryParameters(credential)
if err != nil {
c.Fatal(err)
}
parts := NewBlobURLParts(blobURL.URL())
parts.SAS = sasQueryParams
parts.Snapshot = currentTime.Format(SnapshotTimeFormat)
testURL := parts.URL()
// The snapshot format string is taken from the snapshotTimeFormat value in parsing_urls.go. The field is not public, so
// it is copied here
correctURL := "https://" + os.Getenv("ACCOUNT_NAME") + ".blob.core.windows.net/" + containerName + "/" + blobName +
"?" + "snapshot=" + currentTime.Format("2006-01-02T15:04:05.0000000Z07:00") + "&" + sasQueryParams.Encode()
c.Assert(testURL.String(), chk.Equals, correctURL)
}
func (s *aztestsSuite) TestBlobWithNewPipeline(c *chk.C) {
bsu := getBSU()
containerURL, _ := getContainerURL(c, bsu)
blobURL := containerURL.NewBlockBlobURL(blobPrefix)
newBlobURL := blobURL.WithPipeline(testPipeline{})
_, err := newBlobURL.GetBlockList(ctx, BlockListAll, LeaseAccessConditions{})
c.Assert(err, chk.NotNil)
c.Assert(err.Error(), chk.Equals, testPipelineMessage)
}
func waitForCopy(c *chk.C, copyBlobURL BlockBlobURL, blobCopyResponse *BlobStartCopyFromURLResponse) {
status := blobCopyResponse.CopyStatus()
// Wait for the copy to finish. If the copy takes longer than a minute, we will fail
start := time.Now()
for status != CopyStatusSuccess {
props, _ := copyBlobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
status = props.CopyStatus()
currentTime := time.Now()
if currentTime.Sub(start) >= time.Minute {
c.Fail()
}
}
}
func (s *aztestsSuite) TestBlobStartCopyDestEmpty(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
copyBlobURL, _ := getBlockBlobURL(c, containerURL)
blobCopyResponse, err := copyBlobURL.StartCopyFromURL(ctx, blobURL.URL(), nil, ModifiedAccessConditions{}, BlobAccessConditions{}, DefaultAccessTier, nil)
c.Assert(err, chk.IsNil)
waitForCopy(c, copyBlobURL, blobCopyResponse)
resp, err := copyBlobURL.Download(ctx, 0, 20, BlobAccessConditions{}, false, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
// Read the blob data to verify the copy
data, err := ioutil.ReadAll(resp.Response().Body)
c.Assert(resp.ContentLength(), chk.Equals, int64(len(blockBlobDefaultData)))
c.Assert(string(data), chk.Equals, blockBlobDefaultData)
resp.Body(RetryReaderOptions{}).Close()
}
func (s *aztestsSuite) TestBlobStartCopyMetadata(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
copyBlobURL, _ := getBlockBlobURL(c, containerURL)
resp, err := copyBlobURL.StartCopyFromURL(ctx, blobURL.URL(), basicMetadata, ModifiedAccessConditions{}, BlobAccessConditions{}, DefaultAccessTier, nil)
c.Assert(err, chk.IsNil)
waitForCopy(c, copyBlobURL, resp)
resp2, err := copyBlobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp2.NewMetadata(), chk.DeepEquals, basicMetadata)
}
func (s *aztestsSuite) TestBlobStartCopyMetadataNil(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
copyBlobURL, _ := getBlockBlobURL(c, containerURL)
// Have the destination start with metadata so we ensure the nil metadata passed later takes effect
_, err := copyBlobURL.Upload(ctx, bytes.NewReader([]byte("data")), BlobHTTPHeaders{}, basicMetadata, BlobAccessConditions{}, DefaultAccessTier, nil, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
resp, err := copyBlobURL.StartCopyFromURL(ctx, blobURL.URL(), nil, ModifiedAccessConditions{}, BlobAccessConditions{}, DefaultAccessTier, nil)
c.Assert(err, chk.IsNil)
waitForCopy(c, copyBlobURL, resp)
resp2, err := copyBlobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp2.NewMetadata(), chk.HasLen, 0)
}
func (s *aztestsSuite) TestBlobStartCopyMetadataEmpty(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
copyBlobURL, _ := getBlockBlobURL(c, containerURL)
// Have the destination start with metadata so we ensure the empty metadata passed later takes effect
_, err := copyBlobURL.Upload(ctx, bytes.NewReader([]byte("data")), BlobHTTPHeaders{}, basicMetadata, BlobAccessConditions{}, DefaultAccessTier, nil, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
resp, err := copyBlobURL.StartCopyFromURL(ctx, blobURL.URL(), Metadata{}, ModifiedAccessConditions{}, BlobAccessConditions{}, DefaultAccessTier, nil)
c.Assert(err, chk.IsNil)
waitForCopy(c, copyBlobURL, resp)
resp2, err := copyBlobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp2.NewMetadata(), chk.HasLen, 0)
}
func (s *aztestsSuite) TestBlobStartCopyMetadataInvalidField(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
copyBlobURL, _ := getBlockBlobURL(c, containerURL)
_, err := copyBlobURL.StartCopyFromURL(ctx, blobURL.URL(), Metadata{"I nvalid.": "bar"}, ModifiedAccessConditions{}, BlobAccessConditions{}, DefaultAccessTier, nil)
c.Assert(err, chk.NotNil)
c.Assert(strings.Contains(err.Error(), invalidHeaderErrorSubstring), chk.Equals, true)
}
func (s *aztestsSuite) TestBlobStartCopySourceNonExistant(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := getBlockBlobURL(c, containerURL)
copyBlobURL, _ := getBlockBlobURL(c, containerURL)
_, err := copyBlobURL.StartCopyFromURL(ctx, blobURL.URL(), nil, ModifiedAccessConditions{}, BlobAccessConditions{}, DefaultAccessTier, nil)
validateStorageError(c, err, ServiceCodeBlobNotFound)
}
func (s *aztestsSuite) TestBlobStartCopySourcePrivate(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
_, err := containerURL.SetAccessPolicy(ctx, PublicAccessNone, nil, ContainerAccessConditions{})
c.Assert(err, chk.IsNil)
blobURL, _ := createNewBlockBlob(c, containerURL)
bsu2, err := getAlternateBSU()
if err != nil {
c.Skip(err.Error())
return
}
copyContainerURL, _ := createNewContainer(c, bsu2)
defer deleteContainer(c, copyContainerURL)
copyBlobURL, _ := getBlockBlobURL(c, copyContainerURL)
if bsu.String() == bsu2.String() {
c.Skip("Test not valid because primary and secondary accounts are the same")
}
_, err = copyBlobURL.StartCopyFromURL(ctx, blobURL.URL(), nil, ModifiedAccessConditions{}, BlobAccessConditions{}, DefaultAccessTier, nil)
validateStorageError(c, err, ServiceCodeCannotVerifyCopySource)
}
func (s *aztestsSuite) TestBlobStartCopyUsingSASSrc(c *chk.C) {
bsu := getBSU()
containerURL, containerName := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
_, err := containerURL.SetAccessPolicy(ctx, PublicAccessNone, nil, ContainerAccessConditions{})
c.Assert(err, chk.IsNil)
blobURL, blobName := createNewBlockBlob(c, containerURL)
// Create sas values for the source blob
credential, err := getGenericCredential("")
if err != nil {
c.Fatal("Invalid credential")
}
serviceSASValues := BlobSASSignatureValues{StartTime: time.Now().Add(-1 * time.Hour).UTC(),
ExpiryTime: time.Now().Add(time.Hour).UTC(), Permissions: BlobSASPermissions{Read: true, Write: true}.String(),
ContainerName: containerName, BlobName: blobName}
queryParams, err := serviceSASValues.NewSASQueryParameters(credential)
if err != nil {
c.Fatal(err)
}
// Create URLs to the destination blob with sas parameters
sasURL := blobURL.URL()
sasURL.RawQuery = queryParams.Encode()
// Create a new container for the destination
bsu2, err := getAlternateBSU()
if err != nil {
c.Skip(err.Error())
return
}
copyContainerURL, _ := createNewContainer(c, bsu2)
defer deleteContainer(c, copyContainerURL)
copyBlobURL, _ := getBlockBlobURL(c, copyContainerURL)
resp, err := copyBlobURL.StartCopyFromURL(ctx, sasURL, nil, ModifiedAccessConditions{}, BlobAccessConditions{}, DefaultAccessTier, nil)
c.Assert(err, chk.IsNil)
waitForCopy(c, copyBlobURL, resp)
resp2, err := copyBlobURL.Download(ctx, 0, int64(len(blockBlobDefaultData)), BlobAccessConditions{}, false, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
data, err := ioutil.ReadAll(resp2.Response().Body)
c.Assert(resp2.ContentLength(), chk.Equals, int64(len(blockBlobDefaultData)))
c.Assert(string(data), chk.Equals, blockBlobDefaultData)
resp2.Body(RetryReaderOptions{}).Close()
}
func (s *aztestsSuite) TestBlobStartCopyUsingSASDest(c *chk.C) {
bsu := getBSU()
containerURL, containerName := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
_, err := containerURL.SetAccessPolicy(ctx, PublicAccessNone, nil, ContainerAccessConditions{})
c.Assert(err, chk.IsNil)
blobURL, blobName := createNewBlockBlob(c, containerURL)
_ = blobURL
// Generate SAS on the source
serviceSASValues := BlobSASSignatureValues{ExpiryTime: time.Now().Add(time.Hour).UTC(),
Permissions: BlobSASPermissions{Read: true, Write: true, Create: true}.String(), ContainerName: containerName, BlobName: blobName}
credential, err := getGenericCredential("")
if err != nil {
c.Fatal("Invalid credential")
}
queryParams, err := serviceSASValues.NewSASQueryParameters(credential)
if err != nil {
c.Fatal(err)
}
// Create destination container
bsu2, err := getAlternateBSU()
if err != nil {
c.Skip(err.Error())
return
}
copyContainerURL, copyContainerName := createNewContainer(c, bsu2)
defer deleteContainer(c, copyContainerURL)
copyBlobURL, copyBlobName := getBlockBlobURL(c, copyContainerURL)
// Generate Sas for the destination
credential, err = getGenericCredential("SECONDARY_")
if err != nil {
c.Fatal("Invalid secondary credential")
}
copyServiceSASvalues := BlobSASSignatureValues{StartTime: time.Now().Add(-1 * time.Hour).UTC(),
ExpiryTime: time.Now().Add(time.Hour).UTC(), Permissions: BlobSASPermissions{Read: true, Write: true}.String(),
ContainerName: copyContainerName, BlobName: copyBlobName}
copyQueryParams, err := copyServiceSASvalues.NewSASQueryParameters(credential)
if err != nil {
c.Fatal(err)
}
// Generate anonymous URL to destination with SAS
anonURL := bsu2.URL()
anonURL.RawQuery = copyQueryParams.Encode()
anonPipeline := NewPipeline(NewAnonymousCredential(), PipelineOptions{})
anonBSU := NewServiceURL(anonURL, anonPipeline)
anonContainerURL := anonBSU.NewContainerURL(copyContainerName)
anonBlobURL := anonContainerURL.NewBlockBlobURL(copyBlobName)
// Apply sas to source
srcBlobWithSasURL := blobURL.URL()
srcBlobWithSasURL.RawQuery = queryParams.Encode()
resp, err := anonBlobURL.StartCopyFromURL(ctx, srcBlobWithSasURL, nil, ModifiedAccessConditions{}, BlobAccessConditions{}, DefaultAccessTier, nil)
c.Assert(err, chk.IsNil)
// Allow copy to happen
waitForCopy(c, anonBlobURL, resp)
resp2, err := copyBlobURL.Download(ctx, 0, int64(len(blockBlobDefaultData)), BlobAccessConditions{}, false, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
data, err := ioutil.ReadAll(resp2.Response().Body)
_, err = resp2.Body(RetryReaderOptions{}).Read(data)
c.Assert(resp2.ContentLength(), chk.Equals, int64(len(blockBlobDefaultData)))
c.Assert(string(data), chk.Equals, blockBlobDefaultData)
resp2.Body(RetryReaderOptions{}).Close()
}
func (s *aztestsSuite) TestBlobStartCopySourceIfModifiedSinceTrue(c *chk.C) {
currentTime := getRelativeTimeGMT(-10)
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
destBlobURL, _ := getBlockBlobURL(c, containerURL)
_, err := destBlobURL.StartCopyFromURL(ctx, blobURL.URL(), basicMetadata, ModifiedAccessConditions{IfModifiedSince: currentTime}, BlobAccessConditions{}, DefaultAccessTier, nil)
c.Assert(err, chk.IsNil)
resp, err := destBlobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp.NewMetadata(), chk.DeepEquals, basicMetadata)
}
func (s *aztestsSuite) TestBlobStartCopySourceIfModifiedSinceFalse(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
currentTime := getRelativeTimeGMT(10)
destBlobURL, _ := getBlockBlobURL(c, containerURL)
_, err := destBlobURL.StartCopyFromURL(ctx, blobURL.URL(), nil, ModifiedAccessConditions{IfModifiedSince: currentTime}, BlobAccessConditions{}, DefaultAccessTier, nil)
validateStorageError(c, err, ServiceCodeSourceConditionNotMet)
}
func (s *aztestsSuite) TestBlobStartCopySourceIfUnmodifiedSinceTrue(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
currentTime := getRelativeTimeGMT(10)
destBlobURL, _ := getBlockBlobURL(c, containerURL)
_, err := destBlobURL.StartCopyFromURL(ctx, blobURL.URL(), basicMetadata, ModifiedAccessConditions{IfUnmodifiedSince: currentTime}, BlobAccessConditions{}, DefaultAccessTier, nil)
c.Assert(err, chk.IsNil)
resp, err := destBlobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp.NewMetadata(), chk.DeepEquals, basicMetadata)
}
func (s *aztestsSuite) TestBlobStartCopySourceIfUnmodifiedSinceFalse(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
currentTime := getRelativeTimeGMT(-10)
destBlobURL, _ := getBlockBlobURL(c, containerURL)
_, err := destBlobURL.StartCopyFromURL(ctx, blobURL.URL(), nil, ModifiedAccessConditions{IfUnmodifiedSince: currentTime}, BlobAccessConditions{}, DefaultAccessTier, nil)
validateStorageError(c, err, ServiceCodeSourceConditionNotMet)
}
func (s *aztestsSuite) TestBlobStartCopySourceIfMatchTrue(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
etag := resp.ETag()
destBlobURL, _ := getBlockBlobURL(c, containerURL)
_, err = destBlobURL.StartCopyFromURL(ctx, blobURL.URL(), basicMetadata, ModifiedAccessConditions{IfMatch: etag}, BlobAccessConditions{}, DefaultAccessTier, nil)
c.Assert(err, chk.IsNil)
resp2, err := destBlobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp2.NewMetadata(), chk.DeepEquals, basicMetadata)
}
func (s *aztestsSuite) TestBlobStartCopySourceIfMatchFalse(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
destBlobURL, _ := getBlockBlobURL(c, containerURL)
_, err := destBlobURL.StartCopyFromURL(ctx, blobURL.URL(), basicMetadata, ModifiedAccessConditions{IfMatch: "a"}, BlobAccessConditions{}, DefaultAccessTier, nil)
validateStorageError(c, err, ServiceCodeSourceConditionNotMet)
}
func (s *aztestsSuite) TestBlobStartCopySourceIfNoneMatchTrue(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
destBlobURL, _ := getBlockBlobURL(c, containerURL)
_, err := destBlobURL.StartCopyFromURL(ctx, blobURL.URL(), basicMetadata, ModifiedAccessConditions{IfNoneMatch: "a"}, BlobAccessConditions{}, DefaultAccessTier, nil)
c.Assert(err, chk.IsNil)
resp2, err := destBlobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp2.NewMetadata(), chk.DeepEquals, basicMetadata)
}
func (s *aztestsSuite) TestBlobStartCopySourceIfNoneMatchFalse(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
etag := resp.ETag()
destBlobURL, _ := getBlockBlobURL(c, containerURL)
_, err = destBlobURL.StartCopyFromURL(ctx, blobURL.URL(), nil, ModifiedAccessConditions{IfNoneMatch: etag}, BlobAccessConditions{}, DefaultAccessTier, nil)
validateStorageError(c, err, ServiceCodeSourceConditionNotMet)
}
func (s *aztestsSuite) TestBlobStartCopyDestIfModifiedSinceTrue(c *chk.C) {
currentTime := getRelativeTimeGMT(-10)
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
destBlobURL, _ := createNewBlockBlob(c, containerURL) // The blob must exist to have a last-modified time
_, err := destBlobURL.StartCopyFromURL(ctx, blobURL.URL(), basicMetadata, ModifiedAccessConditions{}, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}}, DefaultAccessTier, nil)
c.Assert(err, chk.IsNil)
resp, err := destBlobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp.NewMetadata(), chk.DeepEquals, basicMetadata)
}
func (s *aztestsSuite) TestBlobStartCopyDestIfModifiedSinceFalse(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
destBlobURL, _ := createNewBlockBlob(c, containerURL)
currentTime := getRelativeTimeGMT(10)
_, err := destBlobURL.StartCopyFromURL(ctx, blobURL.URL(), nil, ModifiedAccessConditions{}, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}}, DefaultAccessTier, nil)
validateStorageError(c, err, ServiceCodeTargetConditionNotMet)
}
func (s *aztestsSuite) TestBlobStartCopyDestIfUnmodifiedSinceTrue(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
destBlobURL, _ := createNewBlockBlob(c, containerURL)
currentTime := getRelativeTimeGMT(10)
_, err := destBlobURL.StartCopyFromURL(ctx, blobURL.URL(), basicMetadata, ModifiedAccessConditions{}, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}}, DefaultAccessTier, nil)
c.Assert(err, chk.IsNil)
resp, err := destBlobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp.NewMetadata(), chk.DeepEquals, basicMetadata)
}
func (s *aztestsSuite) TestBlobStartCopyDestIfUnmodifiedSinceFalse(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
currentTime := getRelativeTimeGMT(-10)
destBlobURL, _ := createNewBlockBlob(c, containerURL)
_, err := destBlobURL.StartCopyFromURL(ctx, blobURL.URL(), nil, ModifiedAccessConditions{}, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}}, DefaultAccessTier, nil)
validateStorageError(c, err, ServiceCodeTargetConditionNotMet)
}
func (s *aztestsSuite) TestBlobStartCopyDestIfMatchTrue(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
destBlobURL, _ := createNewBlockBlob(c, containerURL)
resp, _ := destBlobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
etag := resp.ETag()
_, err := destBlobURL.StartCopyFromURL(ctx, blobURL.URL(), basicMetadata, ModifiedAccessConditions{}, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: etag}}, DefaultAccessTier, nil)
c.Assert(err, chk.IsNil)
resp, err = destBlobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp.NewMetadata(), chk.DeepEquals, basicMetadata)
}
func (s *aztestsSuite) TestBlobStartCopyDestIfMatchFalse(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
destBlobURL, _ := createNewBlockBlob(c, containerURL)
resp, _ := destBlobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
etag := resp.ETag()
destBlobURL.SetMetadata(ctx, nil, BlobAccessConditions{}, ClientProvidedKeyOptions{}) // SetMetadata chances the blob's etag
_, err := destBlobURL.StartCopyFromURL(ctx, blobURL.URL(), nil, ModifiedAccessConditions{}, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: etag}}, DefaultAccessTier, nil)
validateStorageError(c, err, ServiceCodeTargetConditionNotMet)
}
func (s *aztestsSuite) TestBlobStartCopyDestIfNoneMatchTrue(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
destBlobURL, _ := createNewBlockBlob(c, containerURL)
resp, _ := destBlobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
etag := resp.ETag()
destBlobURL.SetMetadata(ctx, nil, BlobAccessConditions{}, ClientProvidedKeyOptions{}) // SetMetadata chances the blob's etag
_, err := destBlobURL.StartCopyFromURL(ctx, blobURL.URL(), basicMetadata, ModifiedAccessConditions{}, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfNoneMatch: etag}}, DefaultAccessTier, nil)
c.Assert(err, chk.IsNil)
resp, err = destBlobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp.NewMetadata(), chk.DeepEquals, basicMetadata)
}
func (s *aztestsSuite) TestBlobStartCopyDestIfNoneMatchFalse(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
destBlobURL, _ := createNewBlockBlob(c, containerURL)
resp, _ := destBlobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
etag := resp.ETag()
_, err := destBlobURL.StartCopyFromURL(ctx, blobURL.URL(), nil, ModifiedAccessConditions{}, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfNoneMatch: etag}}, DefaultAccessTier, nil)
validateStorageError(c, err, ServiceCodeTargetConditionNotMet)
}
func (s *aztestsSuite) TestBlobAbortCopyInProgress(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := getBlockBlobURL(c, containerURL)
// Create a large blob that takes time to copy
blobSize := 8 * 1024 * 1024
blobData := make([]byte, blobSize, blobSize)
for i := range blobData {
blobData[i] = byte('a' + i%26)
}
_, err := blobURL.Upload(ctx, bytes.NewReader(blobData), BlobHTTPHeaders{}, nil, BlobAccessConditions{}, DefaultAccessTier, nil, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
containerURL.SetAccessPolicy(ctx, PublicAccessBlob, nil, ContainerAccessConditions{}) // So that we don't have to create a SAS
// Must copy across accounts so it takes time to copy
bsu2, err := getAlternateBSU()
if err != nil {
c.Skip(err.Error())
return
}
copyContainerURL, _ := createNewContainer(c, bsu2)
copyBlobURL, _ := getBlockBlobURL(c, copyContainerURL)
defer deleteContainer(c, copyContainerURL)
resp, err := copyBlobURL.StartCopyFromURL(ctx, blobURL.URL(), nil, ModifiedAccessConditions{}, BlobAccessConditions{}, DefaultAccessTier, nil)
c.Assert(err, chk.IsNil)
c.Assert(resp.CopyStatus(), chk.Equals, CopyStatusPending)
_, err = copyBlobURL.AbortCopyFromURL(ctx, resp.CopyID(), LeaseAccessConditions{})
if err != nil {
// If the error is nil, the test continues as normal.
// If the error is not nil, we want to check if it's because the copy is finished and send a message indicating this.
validateStorageError(c, err, ServiceCodeNoPendingCopyOperation)
c.Error("The test failed because the copy completed because it was aborted")
}
resp2, _ := copyBlobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(resp2.CopyStatus(), chk.Equals, CopyStatusAborted)
}
func (s *aztestsSuite) TestBlobAbortCopyNoCopyStarted(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
copyBlobURL, _ := getBlockBlobURL(c, containerURL)
_, err := copyBlobURL.AbortCopyFromURL(ctx, "copynotstarted", LeaseAccessConditions{})
validateStorageError(c, err, ServiceCodeInvalidQueryParameterValue)
}
func (s *aztestsSuite) TestBlobSnapshotMetadata(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
resp, err := blobURL.CreateSnapshot(ctx, basicMetadata, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
// Since metadata is specified on the snapshot, the snapshot should have its own metadata different from the (empty) metadata on the source
snapshotURL := blobURL.WithSnapshot(resp.Snapshot())
resp2, err := snapshotURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp2.NewMetadata(), chk.DeepEquals, basicMetadata)
}
func (s *aztestsSuite) TestBlobSnapshotMetadataEmpty(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
_, err := blobURL.SetMetadata(ctx, basicMetadata, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
resp, err := blobURL.CreateSnapshot(ctx, Metadata{}, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
// In this case, because no metadata was specified, it should copy the basicMetadata from the source
snapshotURL := blobURL.WithSnapshot(resp.Snapshot())
resp2, err := snapshotURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp2.NewMetadata(), chk.DeepEquals, basicMetadata)
}
func (s *aztestsSuite) TestBlobSnapshotMetadataNil(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
_, err := blobURL.SetMetadata(ctx, basicMetadata, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
resp, err := blobURL.CreateSnapshot(ctx, nil, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
snapshotURL := blobURL.WithSnapshot(resp.Snapshot())
resp2, err := snapshotURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp2.NewMetadata(), chk.DeepEquals, basicMetadata)
}
func (s *aztestsSuite) TestBlobSnapshotMetadataInvalid(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
_, err := blobURL.CreateSnapshot(ctx, Metadata{"Invalid Field!": "value"}, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.NotNil)
c.Assert(strings.Contains(err.Error(), invalidHeaderErrorSubstring), chk.Equals, true)
}
func (s *aztestsSuite) TestBlobSnapshotBlobNotExist(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := getBlockBlobURL(c, containerURL)
_, err := blobURL.CreateSnapshot(ctx, nil, BlobAccessConditions{}, ClientProvidedKeyOptions{})
validateStorageError(c, err, ServiceCodeBlobNotFound)
}
func (s *aztestsSuite) TestBlobSnapshotOfSnapshot(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
snapshotURL := blobURL.WithSnapshot(time.Now().UTC().Format(SnapshotTimeFormat))
// The library allows the server to handle the snapshot of snapshot error
_, err := snapshotURL.CreateSnapshot(ctx, nil, BlobAccessConditions{}, ClientProvidedKeyOptions{})
validateStorageError(c, err, ServiceCodeInvalidQueryParameterValue)
}
func (s *aztestsSuite) TestBlobSnapshotIfModifiedSinceTrue(c *chk.C) {
currentTime := getRelativeTimeGMT(-10)
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
resp, err := blobURL.CreateSnapshot(ctx, nil, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp.Snapshot() != "", chk.Equals, true) // i.e. The snapshot time is not zero. If the service gives us back a snapshot time, it successfully created a snapshot
}
func (s *aztestsSuite) TestBlobSnapshotIfModifiedSinceFalse(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
currentTime := getRelativeTimeGMT(10)
_, err := blobURL.CreateSnapshot(ctx, nil, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}}, ClientProvidedKeyOptions{})
validateStorageError(c, err, ServiceCodeConditionNotMet)
}
func (s *aztestsSuite) TestBlobSnapshotIfUnmodifiedSinceTrue(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
currentTime := getRelativeTimeGMT(10)
resp, err := blobURL.CreateSnapshot(ctx, nil, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp.Snapshot() == "", chk.Equals, false)
}
func (s *aztestsSuite) TestBlobSnapshotIfUnmodifiedSinceFalse(c *chk.C) {
currentTime := getRelativeTimeGMT(-10)
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
_, err := blobURL.CreateSnapshot(ctx, nil, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}}, ClientProvidedKeyOptions{})
validateStorageError(c, err, ServiceCodeConditionNotMet)
}
func (s *aztestsSuite) TestBlobSnapshotIfMatchTrue(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
resp2, err := blobURL.CreateSnapshot(ctx, nil, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: resp.ETag()}}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp2.Snapshot() == "", chk.Equals, false)
}
func (s *aztestsSuite) TestBlobSnapshotIfMatchFalse(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
_, err := blobURL.CreateSnapshot(ctx, nil, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: "garbage"}}, ClientProvidedKeyOptions{})
validateStorageError(c, err, ServiceCodeConditionNotMet)
}
func (s *aztestsSuite) TestBlobSnapshotIfNoneMatchTrue(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
resp, err := blobURL.CreateSnapshot(ctx, nil, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfNoneMatch: "garbage"}}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp.Snapshot() == "", chk.Equals, false)
}
func (s *aztestsSuite) TestBlobSnapshotIfNoneMatchFalse(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
_, err = blobURL.CreateSnapshot(ctx, nil, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfNoneMatch: resp.ETag()}}, ClientProvidedKeyOptions{})
validateStorageError(c, err, ServiceCodeConditionNotMet)
}
func (s *aztestsSuite) TestBlobDownloadDataNonExistantBlob(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := getBlockBlobURL(c, containerURL)
_, err := blobURL.Download(ctx, 0, 0, BlobAccessConditions{}, false, ClientProvidedKeyOptions{})
validateStorageError(c, err, ServiceCodeBlobNotFound)
}
func (s *aztestsSuite) TestBlobDownloadDataNegativeOffset(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
_, err := blobURL.Download(ctx, -1, 0, BlobAccessConditions{}, false, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
}
func (s *aztestsSuite) TestBlobDownloadDataOffsetOutOfRange(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
_, err := blobURL.Download(ctx, int64(len(blockBlobDefaultData)), CountToEnd, BlobAccessConditions{}, false, ClientProvidedKeyOptions{})
validateStorageError(c, err, ServiceCodeInvalidRange)
}
func (s *aztestsSuite) TestBlobDownloadDataCountNegative(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
_, err := blobURL.Download(ctx, 0, -2, BlobAccessConditions{}, false, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
}
func (s *aztestsSuite) TestBlobDownloadDataCountZero(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
resp, err := blobURL.Download(ctx, 0, 0, BlobAccessConditions{}, false, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
// Specifying a count of 0 results in the value being ignored
data, err := ioutil.ReadAll(resp.Response().Body)
c.Assert(err, chk.IsNil)
c.Assert(string(data), chk.Equals, blockBlobDefaultData)
}
func (s *aztestsSuite) TestBlobDownloadDataCountExact(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
resp, err := blobURL.Download(ctx, 0, int64(len(blockBlobDefaultData)), BlobAccessConditions{}, false, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
data, err := ioutil.ReadAll(resp.Response().Body)
c.Assert(err, chk.IsNil)
c.Assert(string(data), chk.Equals, blockBlobDefaultData)
}
func (s *aztestsSuite) TestBlobDownloadDataCountOutOfRange(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
resp, err := blobURL.Download(ctx, 0, int64(len(blockBlobDefaultData))*2, BlobAccessConditions{}, false, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
data, err := ioutil.ReadAll(resp.Response().Body)
c.Assert(err, chk.IsNil)
c.Assert(string(data), chk.Equals, blockBlobDefaultData)
}
func (s *aztestsSuite) TestBlobDownloadDataEmptyRangeStruct(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
resp, err := blobURL.Download(ctx, 0, 0, BlobAccessConditions{}, false, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
data, err := ioutil.ReadAll(resp.Response().Body)
c.Assert(err, chk.IsNil)
c.Assert(string(data), chk.Equals, blockBlobDefaultData)
}
func (s *aztestsSuite) TestBlobDownloadDataContentMD5(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
resp, err := blobURL.Download(ctx, 10, 3, BlobAccessConditions{}, true, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
mdf := md5.Sum([]byte(blockBlobDefaultData)[10:13])
c.Assert(resp.ContentMD5(), chk.DeepEquals, mdf[:])
}
func (s *aztestsSuite) TestBlobDownloadDataIfModifiedSinceTrue(c *chk.C) {
currentTime := getRelativeTimeGMT(-10)
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
resp, err := blobURL.Download(ctx, 0, 0, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}}, false, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp.ContentLength(), chk.Equals, int64(len(blockBlobDefaultData)))
}
func (s *aztestsSuite) TestBlobDownloadDataIfModifiedSinceFalse(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
currentTime := getRelativeTimeGMT(10)
_, err := blobURL.Download(ctx, 0, 0, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}}, false, ClientProvidedKeyOptions{})
serr := err.(StorageError)
c.Assert(serr.Response().StatusCode, chk.Equals, 304) // The server does not return the error in the body even though it is a GET
}
func (s *aztestsSuite) TestBlobDownloadDataIfUnmodifiedSinceTrue(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
currentTime := getRelativeTimeGMT(10)
resp, err := blobURL.Download(ctx, 0, 0, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}}, false, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp.ContentLength(), chk.Equals, int64(len(blockBlobDefaultData)))
}
func (s *aztestsSuite) TestBlobDownloadDataIfUnmodifiedSinceFalse(c *chk.C) {
currentTime := getRelativeTimeGMT(-10)
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
_, err := blobURL.Download(ctx, 0, 0, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}}, false, ClientProvidedKeyOptions{})
validateStorageError(c, err, ServiceCodeConditionNotMet)
}
func (s *aztestsSuite) TestBlobDownloadDataIfMatchTrue(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
etag := resp.ETag()
resp2, err := blobURL.Download(ctx, 0, 0, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: etag}}, false, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp2.ContentLength(), chk.Equals, int64(len(blockBlobDefaultData)))
}
func (s *aztestsSuite) TestBlobDownloadDataIfMatchFalse(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
etag := resp.ETag()
blobURL.SetMetadata(ctx, nil, BlobAccessConditions{}, ClientProvidedKeyOptions{})
_, err = blobURL.Download(ctx, 0, 0, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: etag}}, false, ClientProvidedKeyOptions{})
validateStorageError(c, err, ServiceCodeConditionNotMet)
}
func (s *aztestsSuite) TestBlobDownloadDataIfNoneMatchTrue(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
etag := resp.ETag()
blobURL.SetMetadata(ctx, nil, BlobAccessConditions{}, ClientProvidedKeyOptions{})
resp2, err := blobURL.Download(ctx, 0, 0, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfNoneMatch: etag}}, false, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp2.ContentLength(), chk.Equals, int64(len(blockBlobDefaultData)))
}
func (s *aztestsSuite) TestBlobDownloadDataIfNoneMatchFalse(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
etag := resp.ETag()
_, err = blobURL.Download(ctx, 0, 0, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfNoneMatch: etag}}, false, ClientProvidedKeyOptions{})
serr := err.(StorageError)
c.Assert(serr.Response().StatusCode, chk.Equals, 304) // The server does not return the error in the body even though it is a GET
}
func (s *aztestsSuite) TestBlobDeleteNonExistant(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := getBlockBlobURL(c, containerURL)
_, err := blobURL.Delete(ctx, DeleteSnapshotsOptionInclude, BlobAccessConditions{})
validateStorageError(c, err, ServiceCodeBlobNotFound)
}
func (s *aztestsSuite) TestBlobDeleteSnapshot(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
resp, err := blobURL.CreateSnapshot(ctx, nil, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
snapshotURL := blobURL.WithSnapshot(resp.Snapshot())
_, err = snapshotURL.Delete(ctx, DeleteSnapshotsOptionNone, BlobAccessConditions{})
c.Assert(err, chk.IsNil)
validateBlobDeleted(c, snapshotURL)
}
func (s *aztestsSuite) TestBlobDeleteSnapshotsInclude(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
_, err := blobURL.CreateSnapshot(ctx, nil, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
_, err = blobURL.Delete(ctx, DeleteSnapshotsOptionInclude, BlobAccessConditions{})
c.Assert(err, chk.IsNil)
resp, _ := containerURL.ListBlobsFlatSegment(ctx, Marker{},
ListBlobsSegmentOptions{Details: BlobListingDetails{Snapshots: true}})
c.Assert(resp.Segment.BlobItems, chk.HasLen, 0)
}
func (s *aztestsSuite) TestBlobDeleteSnapshotsOnly(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
_, err := blobURL.CreateSnapshot(ctx, nil, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
_, err = blobURL.Delete(ctx, DeleteSnapshotsOptionOnly, BlobAccessConditions{})
c.Assert(err, chk.IsNil)
resp, _ := containerURL.ListBlobsFlatSegment(ctx, Marker{},
ListBlobsSegmentOptions{Details: BlobListingDetails{Snapshots: true}})
c.Assert(resp.Segment.BlobItems, chk.HasLen, 1)
c.Assert(resp.Segment.BlobItems[0].Snapshot == "", chk.Equals, true)
}
func (s *aztestsSuite) TestBlobDeleteSnapshotsNoneWithSnapshots(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
_, err := blobURL.CreateSnapshot(ctx, nil, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
_, err = blobURL.Delete(ctx, DeleteSnapshotsOptionNone, BlobAccessConditions{})
validateStorageError(c, err, ServiceCodeSnapshotsPresent)
}
func validateBlobDeleted(c *chk.C, blobURL BlockBlobURL) {
_, err := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.NotNil)
serr := err.(StorageError) // Delete blob is a HEAD request and does not return a ServiceCode in the body
c.Assert(serr.Response().StatusCode, chk.Equals, 404)
}
func (s *aztestsSuite) TestBlobDeleteIfModifiedSinceTrue(c *chk.C) {
currentTime := getRelativeTimeGMT(-10)
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
_, err := blobURL.Delete(ctx, DeleteSnapshotsOptionNone,
BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}})
c.Assert(err, chk.IsNil)
validateBlobDeleted(c, blobURL)
}
func (s *aztestsSuite) TestBlobDeleteIfModifiedSinceFalse(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
currentTime := getRelativeTimeGMT(10)
_, err := blobURL.Delete(ctx, DeleteSnapshotsOptionNone,
BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}})
validateStorageError(c, err, ServiceCodeConditionNotMet)
}
func (s *aztestsSuite) TestBlobDeleteIfUnmodifiedSinceTrue(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
currentTime := getRelativeTimeGMT(10)
_, err := blobURL.Delete(ctx, DeleteSnapshotsOptionNone,
BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}})
c.Assert(err, chk.IsNil)
validateBlobDeleted(c, blobURL)
}
func (s *aztestsSuite) TestBlobDeleteIfUnmodifiedSinceFalse(c *chk.C) {
currentTime := getRelativeTimeGMT(-10)
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
_, err := blobURL.Delete(ctx, DeleteSnapshotsOptionNone,
BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}})
validateStorageError(c, err, ServiceCodeConditionNotMet)
}
func (s *aztestsSuite) TestBlobDeleteIfMatchTrue(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
resp, _ := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
etag := resp.ETag()
_, err := blobURL.Delete(ctx, DeleteSnapshotsOptionNone,
BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: etag}})
c.Assert(err, chk.IsNil)
validateBlobDeleted(c, blobURL)
}
func (s *aztestsSuite) TestBlobDeleteIfMatchFalse(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
resp, _ := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
etag := resp.ETag()
blobURL.SetMetadata(ctx, nil, BlobAccessConditions{}, ClientProvidedKeyOptions{})
_, err := blobURL.Delete(ctx, DeleteSnapshotsOptionNone,
BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: etag}})
validateStorageError(c, err, ServiceCodeConditionNotMet)
}
func (s *aztestsSuite) TestBlobDeleteIfNoneMatchTrue(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
resp, _ := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
etag := resp.ETag()
blobURL.SetMetadata(ctx, nil, BlobAccessConditions{}, ClientProvidedKeyOptions{})
_, err := blobURL.Delete(ctx, DeleteSnapshotsOptionNone,
BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfNoneMatch: etag}})
c.Assert(err, chk.IsNil)
validateBlobDeleted(c, blobURL)
}
func (s *aztestsSuite) TestBlobDeleteIfNoneMatchFalse(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
resp, _ := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
etag := resp.ETag()
_, err := blobURL.Delete(ctx, DeleteSnapshotsOptionNone,
BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfNoneMatch: etag}})
validateStorageError(c, err, ServiceCodeConditionNotMet)
}
func (s *aztestsSuite) TestBlobGetPropsAndMetadataIfModifiedSinceTrue(c *chk.C) {
currentTime := getRelativeTimeGMT(-10)
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
_, err := blobURL.SetMetadata(ctx, basicMetadata, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp.NewMetadata(), chk.DeepEquals, basicMetadata)
}
func (s *aztestsSuite) TestBlobGetPropsAndMetadataIfModifiedSinceFalse(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
_, err := blobURL.SetMetadata(ctx, basicMetadata, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
currentTime := getRelativeTimeGMT(10)
_, err = blobURL.GetProperties(ctx, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}}, ClientProvidedKeyOptions{})
c.Assert(err, chk.NotNil)
serr := err.(StorageError)
c.Assert(serr.Response().StatusCode, chk.Equals, 304) // No service code returned for a HEAD
}
func (s *aztestsSuite) TestBlobGetPropsAndMetadataIfUnmodifiedSinceTrue(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
_, err := blobURL.SetMetadata(ctx, basicMetadata, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
currentTime := getRelativeTimeGMT(10)
resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp.NewMetadata(), chk.DeepEquals, basicMetadata)
}
func (s *aztestsSuite) TestBlobGetPropsAndMetadataIfUnmodifiedSinceFalse(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
currentTime := getRelativeTimeGMT(-10)
_, err := blobURL.SetMetadata(ctx, basicMetadata, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
_, err = blobURL.GetProperties(ctx, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}}, ClientProvidedKeyOptions{})
c.Assert(err, chk.NotNil)
serr := err.(StorageError)
c.Assert(serr.Response().StatusCode, chk.Equals, 412)
}
func (s *aztestsSuite) TestBlobGetPropsAndMetadataIfMatchTrue(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
resp, err := blobURL.SetMetadata(ctx, basicMetadata, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
resp2, err := blobURL.GetProperties(ctx, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: resp.ETag()}}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp2.NewMetadata(), chk.DeepEquals, basicMetadata)
}
func (s *aztestsSuite) TestBlobGetPropsOnMissingBlob(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL := containerURL.NewBlobURL("MISSING")
_, err := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.NotNil)
serr := err.(StorageError)
c.Assert(serr.Response().StatusCode, chk.Equals, 404)
c.Assert(serr.ServiceCode(), chk.Equals, ServiceCodeBlobNotFound)
}
func (s *aztestsSuite) TestBlobGetPropsAndMetadataIfMatchFalse(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
_, err := blobURL.GetProperties(ctx, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: ETag("garbage")}}, ClientProvidedKeyOptions{})
c.Assert(err, chk.NotNil)
serr := err.(StorageError)
c.Assert(serr.Response().StatusCode, chk.Equals, 412)
}
func (s *aztestsSuite) TestBlobGetPropsAndMetadataIfNoneMatchTrue(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
_, err := blobURL.SetMetadata(ctx, basicMetadata, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfNoneMatch: ETag("garbage")}}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp.NewMetadata(), chk.DeepEquals, basicMetadata)
}
func (s *aztestsSuite) TestBlobGetPropsAndMetadataIfNoneMatchFalse(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
resp, err := blobURL.SetMetadata(ctx, nil, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
_, err = blobURL.GetProperties(ctx, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfNoneMatch: resp.ETag()}}, ClientProvidedKeyOptions{})
c.Assert(err, chk.NotNil)
serr := err.(StorageError)
c.Assert(serr.Response().StatusCode, chk.Equals, 304)
}
func (s *aztestsSuite) TestBlobSetPropertiesBasic(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
_, err := blobURL.SetHTTPHeaders(ctx, basicHeaders, BlobAccessConditions{})
c.Assert(err, chk.IsNil)
resp, _ := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
h := resp.NewHTTPHeaders()
c.Assert(h, chk.DeepEquals, basicHeaders)
}
func (s *aztestsSuite) TestBlobSetPropertiesEmptyValue(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
_, err := blobURL.SetHTTPHeaders(ctx, BlobHTTPHeaders{ContentType: "my_type"}, BlobAccessConditions{})
c.Assert(err, chk.IsNil)
_, err = blobURL.SetHTTPHeaders(ctx, BlobHTTPHeaders{}, BlobAccessConditions{})
c.Assert(err, chk.IsNil)
resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp.ContentType(), chk.Equals, "")
}
func validatePropertiesSet(c *chk.C, blobURL BlockBlobURL, disposition string) {
resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp.ContentDisposition(), chk.Equals, disposition)
}
func (s *aztestsSuite) TestBlobSetPropertiesIfModifiedSinceTrue(c *chk.C) {
currentTime := getRelativeTimeGMT(-10)
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
_, err := blobURL.SetHTTPHeaders(ctx, BlobHTTPHeaders{ContentDisposition: "my_disposition"},
BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}})
c.Assert(err, chk.IsNil)
validatePropertiesSet(c, blobURL, "my_disposition")
}
func (s *aztestsSuite) TestBlobSetPropertiesIfModifiedSinceFalse(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
currentTime := getRelativeTimeGMT(10)
_, err := blobURL.SetHTTPHeaders(ctx, BlobHTTPHeaders{ContentDisposition: "my_disposition"},
BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}})
validateStorageError(c, err, ServiceCodeConditionNotMet)
}
func (s *aztestsSuite) TestBlobSetPropertiesIfUnmodifiedSinceTrue(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
currentTime := getRelativeTimeGMT(10)
_, err := blobURL.SetHTTPHeaders(ctx, BlobHTTPHeaders{ContentDisposition: "my_disposition"},
BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}})
c.Assert(err, chk.IsNil)
validatePropertiesSet(c, blobURL, "my_disposition")
}
func (s *aztestsSuite) TestBlobSetPropertiesIfUnmodifiedSinceFalse(c *chk.C) {
currentTime := getRelativeTimeGMT(-10)
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
_, err := blobURL.SetHTTPHeaders(ctx, BlobHTTPHeaders{ContentDisposition: "my_disposition"},
BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}})
validateStorageError(c, err, ServiceCodeConditionNotMet)
}
func (s *aztestsSuite) TestBlobSetPropertiesIfMatchTrue(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
_, err = blobURL.SetHTTPHeaders(ctx, BlobHTTPHeaders{ContentDisposition: "my_disposition"},
BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: resp.ETag()}})
c.Assert(err, chk.IsNil)
validatePropertiesSet(c, blobURL, "my_disposition")
}
func (s *aztestsSuite) TestBlobSetPropertiesIfMatchFalse(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
_, err := blobURL.SetHTTPHeaders(ctx, BlobHTTPHeaders{ContentDisposition: "my_disposition"},
BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: ETag("garbage")}})
validateStorageError(c, err, ServiceCodeConditionNotMet)
}
func (s *aztestsSuite) TestBlobSetPropertiesIfNoneMatchTrue(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
_, err := blobURL.SetHTTPHeaders(ctx, BlobHTTPHeaders{ContentDisposition: "my_disposition"},
BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfNoneMatch: ETag("garbage")}})
c.Assert(err, chk.IsNil)
validatePropertiesSet(c, blobURL, "my_disposition")
}
func (s *aztestsSuite) TestBlobSetPropertiesIfNoneMatchFalse(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
_, err = blobURL.SetHTTPHeaders(ctx, BlobHTTPHeaders{ContentDisposition: "my_disposition"},
BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfNoneMatch: resp.ETag()}})
validateStorageError(c, err, ServiceCodeConditionNotMet)
}
func (s *aztestsSuite) TestBlobSetMetadataNil(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
_, err := blobURL.SetMetadata(ctx, Metadata{"not": "nil"}, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
_, err = blobURL.SetMetadata(ctx, nil, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp.NewMetadata(), chk.HasLen, 0)
}
func (s *aztestsSuite) TestBlobSetMetadataEmpty(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
_, err := blobURL.SetMetadata(ctx, Metadata{"not": "nil"}, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
_, err = blobURL.SetMetadata(ctx, Metadata{}, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp.NewMetadata(), chk.HasLen, 0)
}
func (s *aztestsSuite) TestBlobSetMetadataInvalidField(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
_, err := blobURL.SetMetadata(ctx, Metadata{"Invalid field!": "value"}, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.NotNil)
c.Assert(strings.Contains(err.Error(), invalidHeaderErrorSubstring), chk.Equals, true)
}
func validateMetadataSet(c *chk.C, blobURL BlockBlobURL) {
resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp.NewMetadata(), chk.DeepEquals, basicMetadata)
}
func (s *aztestsSuite) TestBlobSetMetadataIfModifiedSinceTrue(c *chk.C) {
currentTime := getRelativeTimeGMT(-10)
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
_, err := blobURL.SetMetadata(ctx, basicMetadata, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
validateMetadataSet(c, blobURL)
}
func (s *aztestsSuite) TestBlobSetMetadataIfModifiedSinceFalse(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
currentTime := getRelativeTimeGMT(10)
_, err := blobURL.SetMetadata(ctx, basicMetadata, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}}, ClientProvidedKeyOptions{})
validateStorageError(c, err, ServiceCodeConditionNotMet)
}
func (s *aztestsSuite) TestBlobSetMetadataIfUnmodifiedSinceTrue(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
currentTime := getRelativeTimeGMT(10)
_, err := blobURL.SetMetadata(ctx, basicMetadata, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
validateMetadataSet(c, blobURL)
}
func (s *aztestsSuite) TestBlobSetMetadataIfUnmodifiedSinceFalse(c *chk.C) {
currentTime := getRelativeTimeGMT(-10)
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
_, err := blobURL.SetMetadata(ctx, basicMetadata, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}}, ClientProvidedKeyOptions{})
validateStorageError(c, err, ServiceCodeConditionNotMet)
}
func (s *aztestsSuite) TestBlobSetMetadataIfMatchTrue(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
_, err = blobURL.SetMetadata(ctx, basicMetadata, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: resp.ETag()}}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
validateMetadataSet(c, blobURL)
}
func (s *aztestsSuite) TestBlobSetMetadataIfMatchFalse(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
_, err := blobURL.SetMetadata(ctx, basicMetadata, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: ETag("garbage")}}, ClientProvidedKeyOptions{})
validateStorageError(c, err, ServiceCodeConditionNotMet)
}
func (s *aztestsSuite) TestBlobSetMetadataIfNoneMatchTrue(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
_, err := blobURL.SetMetadata(ctx, basicMetadata, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfNoneMatch: ETag("garbage")}}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
validateMetadataSet(c, blobURL)
}
func (s *aztestsSuite) TestBlobSetMetadataIfNoneMatchFalse(c *chk.C) {
bsu := getBSU()
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
_, err = blobURL.SetMetadata(ctx, basicMetadata, BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfNoneMatch: resp.ETag()}}, ClientProvidedKeyOptions{})
validateStorageError(c, err, ServiceCodeConditionNotMet)
}
func testBlobsUndeleteImpl(c *chk.C, bsu ServiceURL) error {
//containerURL, _ := createNewContainer(c, bsu)
//defer deleteContainer(c, containerURL)
//blobURL, _ := createNewBlockBlob(c, containerURL)
//
//_, err := blobURL.Delete(ctx, DeleteSnapshotsOptionNone, BlobAccessConditions{})
//c.Assert(err, chk.IsNil) // This call will not have errors related to slow update of service properties, so we assert.
//
//_, err = blobURL.Undelete(ctx)
//if err != nil { // We want to give the wrapper method a chance to check if it was an error related to the service properties update.
// return err
//}
//
//resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{})
//if err != nil {
// return errors.New(string(err.(StorageError).ServiceCode()))
//}
//c.Assert(resp.BlobType(), chk.Equals, BlobBlockBlob) // We could check any property. This is just to double check it was undeleted.
return nil
}
func (s *aztestsSuite) TestBlobsUndelete(c *chk.C) {
bsu := getBSU()
runTestRequiringServiceProperties(c, bsu, string(ServiceCodeBlobNotFound), enableSoftDelete, testBlobsUndeleteImpl, disableSoftDelete)
}
func setAndCheckBlobTier(c *chk.C, containerURL ContainerURL, blobURL BlobURL, tier AccessTierType) {
_, err := blobURL.SetTier(ctx, tier, LeaseAccessConditions{})
c.Assert(err, chk.IsNil)
resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp.AccessTier(), chk.Equals, string(tier))
resp2, err := containerURL.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp2.Segment.BlobItems[0].Properties.AccessTier, chk.Equals, tier)
}
func (s *aztestsSuite) TestBlobSetTierAllTiers(c *chk.C) {
bsu, err := getBlobStorageBSU()
if err != nil {
c.Skip(err.Error())
}
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
setAndCheckBlobTier(c, containerURL, blobURL.BlobURL, AccessTierHot)
setAndCheckBlobTier(c, containerURL, blobURL.BlobURL, AccessTierCool)
setAndCheckBlobTier(c, containerURL, blobURL.BlobURL, AccessTierArchive)
bsu, err = getPremiumBSU()
if err != nil {
c.Skip(err.Error())
}
containerURL, _ = createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
pageBlobURL, _ := createNewPageBlob(c, containerURL)
setAndCheckBlobTier(c, containerURL, pageBlobURL.BlobURL, AccessTierP4)
setAndCheckBlobTier(c, containerURL, pageBlobURL.BlobURL, AccessTierP6)
setAndCheckBlobTier(c, containerURL, pageBlobURL.BlobURL, AccessTierP10)
setAndCheckBlobTier(c, containerURL, pageBlobURL.BlobURL, AccessTierP20)
setAndCheckBlobTier(c, containerURL, pageBlobURL.BlobURL, AccessTierP30)
setAndCheckBlobTier(c, containerURL, pageBlobURL.BlobURL, AccessTierP40)
setAndCheckBlobTier(c, containerURL, pageBlobURL.BlobURL, AccessTierP50)
}
func (s *aztestsSuite) TestBlobTierInferred(c *chk.C) {
bsu, err := getPremiumBSU()
if err != nil {
c.Skip(err.Error())
}
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewPageBlob(c, containerURL)
resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp.AccessTierInferred(), chk.Equals, "true")
resp2, err := containerURL.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp2.Segment.BlobItems[0].Properties.AccessTierInferred, chk.NotNil)
c.Assert(resp2.Segment.BlobItems[0].Properties.AccessTier, chk.Not(chk.Equals), "")
_, err = blobURL.SetTier(ctx, AccessTierP4, LeaseAccessConditions{})
c.Assert(err, chk.IsNil)
resp, err = blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp.AccessTierInferred(), chk.Equals, "")
resp2, err = containerURL.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp2.Segment.BlobItems[0].Properties.AccessTierInferred, chk.IsNil) // AccessTierInferred never returned if false
}
func (s *aztestsSuite) TestBlobArchiveStatus(c *chk.C) {
bsu, err := getBlobStorageBSU()
if err != nil {
c.Skip(err.Error())
}
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
_, err = blobURL.SetTier(ctx, AccessTierArchive, LeaseAccessConditions{})
c.Assert(err, chk.IsNil)
_, err = blobURL.SetTier(ctx, AccessTierCool, LeaseAccessConditions{})
c.Assert(err, chk.IsNil)
resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp.ArchiveStatus(), chk.Equals, string(ArchiveStatusRehydratePendingToCool))
resp2, err := containerURL.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp2.Segment.BlobItems[0].Properties.ArchiveStatus, chk.Equals, ArchiveStatusRehydratePendingToCool)
// delete first blob
_, err = blobURL.Delete(ctx, DeleteSnapshotsOptionNone, BlobAccessConditions{})
c.Assert(err, chk.IsNil)
blobURL, _ = createNewBlockBlob(c, containerURL)
_, err = blobURL.SetTier(ctx, AccessTierArchive, LeaseAccessConditions{})
c.Assert(err, chk.IsNil)
_, err = blobURL.SetTier(ctx, AccessTierHot, LeaseAccessConditions{})
c.Assert(err, chk.IsNil)
resp, err = blobURL.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp.ArchiveStatus(), chk.Equals, string(ArchiveStatusRehydratePendingToHot))
resp2, err = containerURL.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{})
c.Assert(err, chk.IsNil)
c.Assert(resp2.Segment.BlobItems[0].Properties.ArchiveStatus, chk.Equals, ArchiveStatusRehydratePendingToHot)
}
func (s *aztestsSuite) TestBlobTierInvalidValue(c *chk.C) {
bsu, err := getBlobStorageBSU()
if err != nil {
c.Skip(err.Error())
}
containerURL, _ := createNewContainer(c, bsu)
defer deleteContainer(c, containerURL)
blobURL, _ := createNewBlockBlob(c, containerURL)
_, err = blobURL.SetTier(ctx, AccessTierType("garbage"), LeaseAccessConditions{})
validateStorageError(c, err, ServiceCodeInvalidHeaderValue)
}
func (s *aztestsSuite) TestBlobURLPartsSASQueryTimes(c *chk.C) {
StartTimesInputs := []string{
"2020-04-20",
"2020-04-20T07:00Z",
"2020-04-20T07:15:00Z",
"2020-04-20T07:30:00.1234567Z",
}
StartTimesExpected := []time.Time{
time.Date(2020, time.April, 20, 0, 0, 0, 0, time.UTC),
time.Date(2020, time.April, 20, 7, 0, 0, 0, time.UTC),
time.Date(2020, time.April, 20, 7, 15, 0, 0, time.UTC),
time.Date(2020, time.April, 20, 7, 30, 0, 123456700, time.UTC),
}
ExpiryTimesInputs := []string{
"2020-04-21",
"2020-04-20T08:00Z",
"2020-04-20T08:15:00Z",
"2020-04-20T08:30:00.2345678Z",
}
ExpiryTimesExpected := []time.Time{
time.Date(2020, time.April, 21, 0, 0, 0, 0, time.UTC),
time.Date(2020, time.April, 20, 8, 0, 0, 0, time.UTC),
time.Date(2020, time.April, 20, 8, 15, 0, 0, time.UTC),
time.Date(2020, time.April, 20, 8, 30, 0, 234567800, time.UTC),
}
for i := 0; i < len(StartTimesInputs); i++ {
urlString :=
"https://myaccount.blob.core.windows.net/mycontainer/mydirectory/myfile.txt?" +
"se=" + url.QueryEscape(ExpiryTimesInputs[i]) + "&" +
"sig=NotASignature&" +
"sp=r&" +
"spr=https&" +
"sr=b&" +
"st=" + url.QueryEscape(StartTimesInputs[i]) + "&" +
"sv=2019-10-10"
url, _ := url.Parse(urlString)
parts := NewBlobURLParts(*url)
c.Assert(parts.Scheme, chk.Equals, "https")
c.Assert(parts.Host, chk.Equals, "myaccount.blob.core.windows.net")
c.Assert(parts.ContainerName, chk.Equals, "mycontainer")
c.Assert(parts.BlobName, chk.Equals, "mydirectory/myfile.txt")
sas := parts.SAS
c.Assert(sas.StartTime(), chk.Equals, StartTimesExpected[i])
c.Assert(sas.ExpiryTime(), chk.Equals, ExpiryTimesExpected[i])
uResult := parts.URL()
c.Assert(uResult.String(), chk.Equals, urlString)
}
}
func (s *aztestsSuite) TestDownloadBlockBlobUnexpectedEOF(c *chk.C) {
bsu := getBSU()
cURL, _ := createNewContainer(c, bsu)
defer delContainer(c, cURL)
bURL, _ := createNewBlockBlob(c, cURL) // This uploads for us.
resp, err := bURL.Download(ctx, 0, 0, BlobAccessConditions{}, false, ClientProvidedKeyOptions{})
c.Assert(err, chk.IsNil)
// Verify that we can inject errors first.
reader := resp.Body(InjectErrorInRetryReaderOptions(errors.New("unrecoverable error")))
_, err = ioutil.ReadAll(reader)
c.Assert(err, chk.NotNil)
c.Assert(err.Error(), chk.Equals, "unrecoverable error")
// Then inject the retryable error.
reader = resp.Body(InjectErrorInRetryReaderOptions(io.ErrUnexpectedEOF))
buf, err := ioutil.ReadAll(reader)
c.Assert(err, chk.IsNil)
c.Assert(buf, chk.DeepEquals, []byte(blockBlobDefaultData))
}