1070 строки
38 KiB
Go
1070 строки
38 KiB
Go
package azblob
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"errors"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
chk "gopkg.in/check.v1" // go get gopkg.in/check.v1
|
|
)
|
|
|
|
func delContainer(c *chk.C, container ContainerURL) {
|
|
resp, err := container.Delete(context.Background(), ContainerAccessConditions{})
|
|
c.Assert(err, chk.IsNil)
|
|
c.Assert(resp.Response().StatusCode, chk.Equals, 202)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestNewContainerURLValidName(c *chk.C) {
|
|
bsu := getBSU()
|
|
testURL := bsu.NewContainerURL(containerPrefix)
|
|
|
|
correctURL := "https://" + os.Getenv("ACCOUNT_NAME") + ".blob.core.windows.net/" + containerPrefix
|
|
temp := testURL.URL()
|
|
c.Assert(temp.String(), chk.Equals, correctURL)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestCreateRootContainerURL(c *chk.C) {
|
|
bsu := getBSU()
|
|
testURL := bsu.NewContainerURL(ContainerNameRoot)
|
|
|
|
correctURL := "https://" + os.Getenv("ACCOUNT_NAME") + ".blob.core.windows.net/$root"
|
|
temp := testURL.URL()
|
|
c.Assert(temp.String(), chk.Equals, correctURL)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestAccountWithPipeline(c *chk.C) {
|
|
bsu := getBSU()
|
|
bsu = bsu.WithPipeline(testPipeline{}) // testPipeline returns an identifying message as an error
|
|
containerURL := bsu.NewContainerURL("name")
|
|
|
|
_, err := containerURL.Create(ctx, Metadata{}, PublicAccessBlob)
|
|
|
|
c.Assert(err.Error(), chk.Equals, testPipelineMessage)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerCreateInvalidName(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL := bsu.NewContainerURL("foo bar")
|
|
|
|
_, err := containerURL.Create(ctx, Metadata{}, PublicAccessBlob)
|
|
|
|
validateStorageError(c, err, ServiceCodeInvalidResourceName)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerCreateEmptyName(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL := bsu.NewContainerURL("")
|
|
|
|
_, err := containerURL.Create(ctx, Metadata{}, PublicAccessBlob)
|
|
|
|
validateStorageError(c, err, ServiceCodeInvalidQueryParameterValue)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerCreateNameCollision(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, containerName := createNewContainer(c, bsu)
|
|
|
|
defer deleteContainer(c, containerURL)
|
|
|
|
containerURL = bsu.NewContainerURL(containerName)
|
|
_, err := containerURL.Create(ctx, Metadata{}, PublicAccessBlob)
|
|
|
|
validateStorageError(c, err, ServiceCodeContainerAlreadyExists)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerCreateInvalidMetadata(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := getContainerURL(c, bsu)
|
|
|
|
_, err := containerURL.Create(ctx, Metadata{"1 foo": "bar"}, PublicAccessBlob)
|
|
|
|
c.Assert(err, chk.NotNil)
|
|
c.Assert(strings.Contains(err.Error(), invalidHeaderErrorSubstring), chk.Equals, true)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerCreateNilMetadata(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := getContainerURL(c, bsu)
|
|
|
|
_, err := containerURL.Create(ctx, nil, PublicAccessBlob)
|
|
defer deleteContainer(c, containerURL)
|
|
c.Assert(err, chk.IsNil)
|
|
|
|
response, err := containerURL.GetProperties(ctx, LeaseAccessConditions{})
|
|
c.Assert(err, chk.IsNil)
|
|
c.Assert(response.NewMetadata(), chk.HasLen, 0)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerCreateEmptyMetadata(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := getContainerURL(c, bsu)
|
|
|
|
_, err := containerURL.Create(ctx, Metadata{}, PublicAccessBlob)
|
|
defer deleteContainer(c, containerURL)
|
|
c.Assert(err, chk.IsNil)
|
|
|
|
response, err := containerURL.GetProperties(ctx, LeaseAccessConditions{})
|
|
c.Assert(err, chk.IsNil)
|
|
c.Assert(response.NewMetadata(), chk.HasLen, 0)
|
|
}
|
|
|
|
// Note that for all tests that create blobs, deleting the container also deletes any blobs within that container, thus we
|
|
// simply delete the whole container after the test
|
|
|
|
func (s *aztestsSuite) TestContainerCreateAccessContainer(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := getContainerURL(c, bsu)
|
|
|
|
_, err := containerURL.Create(ctx, nil, PublicAccessContainer)
|
|
defer deleteContainer(c, containerURL)
|
|
c.Assert(err, chk.IsNil)
|
|
|
|
blobURL := containerURL.NewBlockBlobURL(blobPrefix)
|
|
blobURL.Upload(ctx, bytes.NewReader([]byte("Content")), BlobHTTPHeaders{}, basicMetadata, BlobAccessConditions{}, DefaultAccessTier, nil, ClientProvidedKeyOptions{})
|
|
|
|
// Anonymous enumeration should be valid with container access
|
|
containerURL2 := NewContainerURL(containerURL.URL(), NewPipeline(NewAnonymousCredential(), PipelineOptions{}))
|
|
response, err := containerURL2.ListBlobsFlatSegment(ctx, Marker{},
|
|
ListBlobsSegmentOptions{})
|
|
c.Assert(err, chk.IsNil)
|
|
c.Assert(response.Segment.BlobItems[0].Name, chk.Equals, blobPrefix)
|
|
|
|
// Getting blob data anonymously should still be valid with container access
|
|
blobURL2 := containerURL2.NewBlockBlobURL(blobPrefix)
|
|
resp, err := blobURL2.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
|
|
c.Assert(err, chk.IsNil)
|
|
c.Assert(resp.NewMetadata(), chk.DeepEquals, basicMetadata)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerCreateAccessBlob(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := getContainerURL(c, bsu)
|
|
|
|
_, err := containerURL.Create(ctx, nil, PublicAccessBlob)
|
|
defer deleteContainer(c, containerURL)
|
|
c.Assert(err, chk.IsNil)
|
|
|
|
blobURL := containerURL.NewBlockBlobURL(blobPrefix)
|
|
blobURL.Upload(ctx, bytes.NewReader([]byte("Content")), BlobHTTPHeaders{}, basicMetadata, BlobAccessConditions{}, DefaultAccessTier, nil, ClientProvidedKeyOptions{})
|
|
|
|
// Reference the same container URL but with anonymous credentials
|
|
containerURL2 := NewContainerURL(containerURL.URL(), NewPipeline(NewAnonymousCredential(), PipelineOptions{}))
|
|
_, err = containerURL2.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{})
|
|
validateStorageError(c, err, ServiceCodeNoAuthenticationInformation) // Listing blobs is not publicly accessible
|
|
|
|
// Accessing blob specific data should be public
|
|
blobURL2 := containerURL2.NewBlockBlobURL(blobPrefix)
|
|
resp, err := blobURL2.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
|
|
c.Assert(err, chk.IsNil)
|
|
c.Assert(resp.NewMetadata(), chk.DeepEquals, basicMetadata)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerCreateAccessNone(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := getContainerURL(c, bsu)
|
|
|
|
_, err := containerURL.Create(ctx, nil, PublicAccessNone)
|
|
defer deleteContainer(c, containerURL)
|
|
|
|
blobURL := containerURL.NewBlockBlobURL(blobPrefix)
|
|
blobURL.Upload(ctx, bytes.NewReader([]byte("Content")), BlobHTTPHeaders{}, basicMetadata, BlobAccessConditions{}, DefaultAccessTier, nil, ClientProvidedKeyOptions{})
|
|
|
|
// Reference the same container URL but with anonymous credentials
|
|
containerURL2 := NewContainerURL(containerURL.URL(), NewPipeline(NewAnonymousCredential(), PipelineOptions{}))
|
|
// Listing blobs is not public
|
|
_, err = containerURL2.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{})
|
|
validateStorageError(c, err, ServiceCodeNoAuthenticationInformation)
|
|
|
|
// Blob data is not public
|
|
blobURL2 := containerURL2.NewBlockBlobURL(blobPrefix)
|
|
_, err = blobURL2.GetProperties(ctx, BlobAccessConditions{}, ClientProvidedKeyOptions{})
|
|
c.Assert(err, chk.NotNil)
|
|
serr := err.(StorageError)
|
|
c.Assert(serr.Response().StatusCode, chk.Equals, 401) // HEAD request does not return a status code
|
|
}
|
|
|
|
func validateContainerDeleted(c *chk.C, containerURL ContainerURL) {
|
|
_, err := containerURL.GetAccessPolicy(ctx, LeaseAccessConditions{})
|
|
validateStorageError(c, err, ServiceCodeContainerNotFound)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerDelete(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := createNewContainer(c, bsu)
|
|
|
|
_, err := containerURL.Delete(ctx, ContainerAccessConditions{})
|
|
c.Assert(err, chk.IsNil)
|
|
|
|
validateContainerDeleted(c, containerURL)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerDeleteNonExistant(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := getContainerURL(c, bsu)
|
|
|
|
_, err := containerURL.Delete(ctx, ContainerAccessConditions{})
|
|
validateStorageError(c, err, ServiceCodeContainerNotFound)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerDeleteIfModifiedSinceTrue(c *chk.C) {
|
|
currentTime := getRelativeTimeGMT(-10) // Ensure the requests occur at different times
|
|
bsu := getBSU()
|
|
containerURL, _ := createNewContainer(c, bsu)
|
|
|
|
_, err := containerURL.Delete(ctx,
|
|
ContainerAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}})
|
|
c.Assert(err, chk.IsNil)
|
|
validateContainerDeleted(c, containerURL)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerDeleteIfModifiedSinceFalse(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := createNewContainer(c, bsu)
|
|
|
|
defer deleteContainer(c, containerURL)
|
|
|
|
currentTime := getRelativeTimeGMT(10)
|
|
|
|
_, err := containerURL.Delete(ctx,
|
|
ContainerAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}})
|
|
validateStorageError(c, err, ServiceCodeConditionNotMet)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerDeleteIfUnModifiedSinceTrue(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := createNewContainer(c, bsu)
|
|
|
|
currentTime := getRelativeTimeGMT(10)
|
|
_, err := containerURL.Delete(ctx,
|
|
ContainerAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}})
|
|
c.Assert(err, chk.IsNil)
|
|
|
|
validateContainerDeleted(c, containerURL)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerDeleteIfUnModifiedSinceFalse(c *chk.C) {
|
|
currentTime := getRelativeTimeGMT(-10) // Ensure the requests occur at different times
|
|
|
|
bsu := getBSU()
|
|
containerURL, _ := createNewContainer(c, bsu)
|
|
|
|
defer deleteContainer(c, containerURL)
|
|
|
|
_, err := containerURL.Delete(ctx,
|
|
ContainerAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}})
|
|
validateStorageError(c, err, ServiceCodeConditionNotMet)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerAccessConditionsUnsupportedConditions(c *chk.C) {
|
|
// This test defines that the library will panic if the user specifies conditional headers
|
|
// that will be ignored by the service
|
|
bsu := getBSU()
|
|
containerURL, _ := createNewContainer(c, bsu)
|
|
defer deleteContainer(c, containerURL)
|
|
|
|
invalidEtag := ETag("invalid")
|
|
_, err := containerURL.SetMetadata(ctx, basicMetadata,
|
|
ContainerAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: invalidEtag}})
|
|
c.Assert(err, chk.Not(chk.Equals), nil)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerListBlobsNonexistantPrefix(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := createNewContainer(c, bsu)
|
|
defer deleteContainer(c, containerURL)
|
|
createNewBlockBlob(c, containerURL)
|
|
|
|
resp, err := containerURL.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{Prefix: blobPrefix + blobPrefix})
|
|
|
|
c.Assert(err, chk.IsNil)
|
|
c.Assert(resp.Segment.BlobItems, chk.HasLen, 0)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerListBlobsSpecificValidPrefix(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := createNewContainer(c, bsu)
|
|
defer deleteContainer(c, containerURL)
|
|
_, blobName := createNewBlockBlob(c, containerURL)
|
|
|
|
resp, err := containerURL.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{Prefix: blobPrefix})
|
|
|
|
c.Assert(err, chk.IsNil)
|
|
c.Assert(resp.Segment.BlobItems, chk.HasLen, 1)
|
|
c.Assert(resp.Segment.BlobItems[0].Name, chk.Equals, blobName)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerListBlobsValidDelimiter(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := createNewContainer(c, bsu)
|
|
defer deleteContainer(c, containerURL)
|
|
createBlockBlobWithPrefix(c, containerURL, "a/1")
|
|
createBlockBlobWithPrefix(c, containerURL, "a/2")
|
|
createBlockBlobWithPrefix(c, containerURL, "b/1")
|
|
_, blobName := createBlockBlobWithPrefix(c, containerURL, "blob")
|
|
|
|
resp, err := containerURL.ListBlobsHierarchySegment(ctx, Marker{}, "/", ListBlobsSegmentOptions{})
|
|
|
|
c.Assert(err, chk.IsNil)
|
|
c.Assert(len(resp.Segment.BlobItems), chk.Equals, 1)
|
|
c.Assert(len(resp.Segment.BlobPrefixes), chk.Equals, 2)
|
|
c.Assert(resp.Segment.BlobPrefixes[0].Name, chk.Equals, "a/")
|
|
c.Assert(resp.Segment.BlobPrefixes[1].Name, chk.Equals, "b/")
|
|
c.Assert(resp.Segment.BlobItems[0].Name, chk.Equals, blobName)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerListBlobsWithSnapshots(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := createNewContainer(c, bsu)
|
|
defer deleteContainer(c, containerURL)
|
|
|
|
_, err := containerURL.ListBlobsHierarchySegment(ctx, Marker{}, "/", ListBlobsSegmentOptions{Details: BlobListingDetails{Snapshots: true}})
|
|
c.Assert(err, chk.Not(chk.Equals), nil)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerListBlobsInvalidDelimiter(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := createNewContainer(c, bsu)
|
|
defer deleteContainer(c, containerURL)
|
|
createBlockBlobWithPrefix(c, containerURL, "a/1")
|
|
createBlockBlobWithPrefix(c, containerURL, "a/2")
|
|
createBlockBlobWithPrefix(c, containerURL, "b/1")
|
|
createBlockBlobWithPrefix(c, containerURL, "blob")
|
|
|
|
resp, err := containerURL.ListBlobsHierarchySegment(ctx, Marker{}, "^", ListBlobsSegmentOptions{})
|
|
|
|
c.Assert(err, chk.IsNil)
|
|
c.Assert(resp.Segment.BlobItems, chk.HasLen, 4)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerListBlobsIncludeTypeMetadata(c *chk.C) {
|
|
bsu := getBSU()
|
|
container, _ := createNewContainer(c, bsu)
|
|
defer deleteContainer(c, container)
|
|
_, blobNameNoMetadata := createBlockBlobWithPrefix(c, container, "a")
|
|
blobMetadata, blobNameMetadata := createBlockBlobWithPrefix(c, container, "b")
|
|
_, err := blobMetadata.SetMetadata(ctx, Metadata{"field": "value"}, BlobAccessConditions{}, ClientProvidedKeyOptions{})
|
|
c.Assert(err, chk.IsNil)
|
|
|
|
resp, err := container.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{Details: BlobListingDetails{Metadata: true}})
|
|
|
|
c.Assert(err, chk.IsNil)
|
|
c.Assert(resp.Segment.BlobItems[0].Name, chk.Equals, blobNameNoMetadata)
|
|
c.Assert(resp.Segment.BlobItems[0].Metadata, chk.HasLen, 0)
|
|
c.Assert(resp.Segment.BlobItems[1].Name, chk.Equals, blobNameMetadata)
|
|
c.Assert(resp.Segment.BlobItems[1].Metadata["field"], chk.Equals, "value")
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerListBlobsIncludeTypeSnapshots(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := createNewContainer(c, bsu)
|
|
defer deleteContainer(c, containerURL)
|
|
blob, blobName := createNewBlockBlob(c, containerURL)
|
|
_, err := blob.CreateSnapshot(ctx, Metadata{}, BlobAccessConditions{}, ClientProvidedKeyOptions{})
|
|
c.Assert(err, chk.IsNil)
|
|
|
|
resp, err := containerURL.ListBlobsFlatSegment(ctx, Marker{},
|
|
ListBlobsSegmentOptions{Details: BlobListingDetails{Snapshots: true}})
|
|
|
|
c.Assert(err, chk.IsNil)
|
|
c.Assert(resp.Segment.BlobItems, chk.HasLen, 2)
|
|
c.Assert(resp.Segment.BlobItems[0].Name, chk.Equals, blobName)
|
|
c.Assert(resp.Segment.BlobItems[0].Snapshot, chk.NotNil)
|
|
c.Assert(resp.Segment.BlobItems[1].Name, chk.Equals, blobName)
|
|
c.Assert(resp.Segment.BlobItems[1].Snapshot, chk.Equals, "")
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerListBlobsIncludeTypeCopy(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := createNewContainer(c, bsu)
|
|
defer deleteContainer(c, containerURL)
|
|
blobURL, blobName := createNewBlockBlob(c, containerURL)
|
|
blobCopyURL, blobCopyName := createBlockBlobWithPrefix(c, containerURL, "copy")
|
|
_, err := blobCopyURL.StartCopyFromURL(ctx, blobURL.URL(), Metadata{}, ModifiedAccessConditions{}, BlobAccessConditions{}, DefaultAccessTier, nil)
|
|
c.Assert(err, chk.IsNil)
|
|
|
|
resp, err := containerURL.ListBlobsFlatSegment(ctx, Marker{},
|
|
ListBlobsSegmentOptions{Details: BlobListingDetails{Copy: true}})
|
|
|
|
// These are sufficient to show that the blob copy was in fact included
|
|
c.Assert(err, chk.IsNil)
|
|
c.Assert(resp.Segment.BlobItems, chk.HasLen, 2)
|
|
c.Assert(resp.Segment.BlobItems[1].Name, chk.Equals, blobName)
|
|
c.Assert(resp.Segment.BlobItems[0].Name, chk.Equals, blobCopyName)
|
|
c.Assert(*resp.Segment.BlobItems[0].Properties.ContentLength, chk.Equals, int64(len(blockBlobDefaultData)))
|
|
temp := blobURL.URL()
|
|
c.Assert(*resp.Segment.BlobItems[0].Properties.CopySource, chk.Equals, temp.String())
|
|
c.Assert(resp.Segment.BlobItems[0].Properties.CopyStatus, chk.Equals, CopyStatusSuccess)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerListBlobsIncludeTypeUncommitted(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := createNewContainer(c, bsu)
|
|
defer deleteContainer(c, containerURL)
|
|
blobURL, blobName := getBlockBlobURL(c, containerURL)
|
|
_, err := blobURL.StageBlock(ctx, blockID, strings.NewReader(blockBlobDefaultData), LeaseAccessConditions{}, nil, ClientProvidedKeyOptions{})
|
|
c.Assert(err, chk.IsNil)
|
|
|
|
resp, err := containerURL.ListBlobsFlatSegment(ctx, Marker{},
|
|
ListBlobsSegmentOptions{Details: BlobListingDetails{UncommittedBlobs: true}})
|
|
|
|
c.Assert(err, chk.IsNil)
|
|
c.Assert(resp.Segment.BlobItems, chk.HasLen, 1)
|
|
c.Assert(resp.Segment.BlobItems[0].Name, chk.Equals, blobName)
|
|
}
|
|
|
|
func testContainerListBlobsIncludeTypeDeletedImpl(c *chk.C, bsu ServiceURL) error {
|
|
containerURL, _ := createNewContainer(c, bsu)
|
|
defer deleteContainer(c, containerURL)
|
|
blobURL, _ := createNewBlockBlob(c, containerURL)
|
|
|
|
resp, err := containerURL.ListBlobsFlatSegment(ctx, Marker{},
|
|
ListBlobsSegmentOptions{Details: BlobListingDetails{Versions: true, Deleted: true}})
|
|
c.Assert(err, chk.IsNil)
|
|
c.Assert(resp.Segment.BlobItems, chk.HasLen, 1)
|
|
|
|
_, err = blobURL.Delete(ctx, DeleteSnapshotsOptionInclude, BlobAccessConditions{})
|
|
c.Assert(err, chk.IsNil)
|
|
|
|
resp, err = containerURL.ListBlobsFlatSegment(ctx, Marker{},
|
|
ListBlobsSegmentOptions{Details: BlobListingDetails{Versions: true, Deleted: true}})
|
|
c.Assert(err, chk.IsNil)
|
|
if len(resp.Segment.BlobItems) != 1 {
|
|
return errors.New("DeletedBlobNotFound")
|
|
}
|
|
|
|
// TODO: => Write function to enable/disable versioning from code itself.
|
|
// resp.Segment.BlobItems[0].Deleted == true/false if versioning is disabled/enabled.
|
|
c.Assert(resp.Segment.BlobItems[0].Deleted, chk.Equals, false)
|
|
return nil
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerListBlobsIncludeTypeDeleted(c *chk.C) {
|
|
bsu := getBSU()
|
|
|
|
runTestRequiringServiceProperties(c, bsu, "DeletedBlobNotFound", enableSoftDelete,
|
|
testContainerListBlobsIncludeTypeDeletedImpl, disableSoftDelete)
|
|
}
|
|
|
|
func testContainerListBlobsIncludeMultipleImpl(c *chk.C, bsu ServiceURL) error {
|
|
containerURL, _ := createNewContainer(c, bsu)
|
|
defer deleteContainer(c, containerURL)
|
|
|
|
blobURL, _ := createBlockBlobWithPrefix(c, containerURL, "z")
|
|
_, err := blobURL.CreateSnapshot(ctx, Metadata{}, BlobAccessConditions{}, ClientProvidedKeyOptions{})
|
|
c.Assert(err, chk.IsNil)
|
|
blobURL2, _ := createBlockBlobWithPrefix(c, containerURL, "copy")
|
|
resp2, err := blobURL2.StartCopyFromURL(ctx, blobURL.URL(), Metadata{}, ModifiedAccessConditions{}, BlobAccessConditions{}, DefaultAccessTier, nil)
|
|
c.Assert(err, chk.IsNil)
|
|
waitForCopy(c, blobURL2, resp2)
|
|
blobURL3, _ := createBlockBlobWithPrefix(c, containerURL, "deleted")
|
|
|
|
_, err = blobURL3.Delete(ctx, DeleteSnapshotsOptionNone, BlobAccessConditions{})
|
|
|
|
resp, err := containerURL.ListBlobsFlatSegment(ctx, Marker{},
|
|
ListBlobsSegmentOptions{Details: BlobListingDetails{Snapshots: true, Copy: true, Deleted: true, Versions: true}})
|
|
|
|
c.Assert(err, chk.IsNil)
|
|
if len(resp.Segment.BlobItems) != 6 {
|
|
// If there are fewer blobs in the container than there should be, it will be because one was permanently deleted.
|
|
return errors.New("DeletedBlobNotFound")
|
|
}
|
|
|
|
//c.Assert(resp.Segment.BlobItems[0].Name, chk.Equals, blobName2)
|
|
//c.Assert(resp.Segment.BlobItems[1].Name, chk.Equals, blobName) // With soft delete, the overwritten blob will have a backup snapshot
|
|
//c.Assert(resp.Segment.BlobItems[2].Name, chk.Equals, blobName)
|
|
return nil
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerListBlobsIncludeMultiple(c *chk.C) {
|
|
bsu := getBSU()
|
|
|
|
runTestRequiringServiceProperties(c, bsu, "DeletedBlobNotFound", enableSoftDelete,
|
|
testContainerListBlobsIncludeMultipleImpl, disableSoftDelete)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerListBlobsMaxResultsNegative(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := createNewContainer(c, bsu)
|
|
|
|
defer deleteContainer(c, containerURL)
|
|
_, err := containerURL.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{MaxResults: -2})
|
|
c.Assert(err, chk.Not(chk.IsNil))
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerListBlobsMaxResultsZero(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := createNewContainer(c, bsu)
|
|
defer deleteContainer(c, containerURL)
|
|
createNewBlockBlob(c, containerURL)
|
|
|
|
resp, err := containerURL.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{MaxResults: 0})
|
|
|
|
c.Assert(err, chk.IsNil)
|
|
c.Assert(resp.Segment.BlobItems, chk.HasLen, 1)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerListBlobsMaxResultsInsufficient(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := createNewContainer(c, bsu)
|
|
defer deleteContainer(c, containerURL)
|
|
_, blobName := createBlockBlobWithPrefix(c, containerURL, "a")
|
|
createBlockBlobWithPrefix(c, containerURL, "b")
|
|
|
|
resp, err := containerURL.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{MaxResults: 1})
|
|
|
|
c.Assert(err, chk.IsNil)
|
|
c.Assert(resp.Segment.BlobItems, chk.HasLen, 1)
|
|
c.Assert(resp.Segment.BlobItems[0].Name, chk.Equals, blobName)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerListBlobsMaxResultsExact(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := createNewContainer(c, bsu)
|
|
defer deleteContainer(c, containerURL)
|
|
_, blobName := createBlockBlobWithPrefix(c, containerURL, "a")
|
|
_, blobName2 := createBlockBlobWithPrefix(c, containerURL, "b")
|
|
|
|
resp, err := containerURL.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{MaxResults: 2})
|
|
|
|
c.Assert(err, chk.IsNil)
|
|
c.Assert(resp.Segment.BlobItems, chk.HasLen, 2)
|
|
c.Assert(resp.Segment.BlobItems[0].Name, chk.Equals, blobName)
|
|
c.Assert(resp.Segment.BlobItems[1].Name, chk.Equals, blobName2)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerListBlobsMaxResultsSufficient(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := createNewContainer(c, bsu)
|
|
defer deleteContainer(c, containerURL)
|
|
_, blobName := createBlockBlobWithPrefix(c, containerURL, "a")
|
|
_, blobName2 := createBlockBlobWithPrefix(c, containerURL, "b")
|
|
|
|
resp, err := containerURL.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{MaxResults: 3})
|
|
|
|
c.Assert(err, chk.IsNil)
|
|
c.Assert(resp.Segment.BlobItems, chk.HasLen, 2)
|
|
c.Assert(resp.Segment.BlobItems[0].Name, chk.Equals, blobName)
|
|
c.Assert(resp.Segment.BlobItems[1].Name, chk.Equals, blobName2)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerListBlobsNonExistentContainer(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := getContainerURL(c, bsu)
|
|
|
|
_, err := containerURL.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{})
|
|
|
|
c.Assert(err, chk.NotNil)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerWithNewPipeline(c *chk.C) {
|
|
bsu := getBSU()
|
|
pipeline := testPipeline{}
|
|
containerURL, _ := getContainerURL(c, bsu)
|
|
containerURL = containerURL.WithPipeline(pipeline)
|
|
|
|
_, err := containerURL.Create(ctx, Metadata{}, PublicAccessBlob)
|
|
|
|
c.Assert(err, chk.NotNil)
|
|
c.Assert(err.Error(), chk.Equals, testPipelineMessage)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerGetSetPermissionsMultiplePolicies(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := createNewContainer(c, bsu)
|
|
|
|
defer deleteContainer(c, containerURL)
|
|
|
|
// Define the policies
|
|
start := generateCurrentTimeWithModerateResolution()
|
|
expiry := start.Add(5 * time.Minute)
|
|
expiry2 := start.Add(time.Minute)
|
|
readWrite := AccessPolicyPermission{Read: true, Write: true}.String()
|
|
readOnly := AccessPolicyPermission{Read: true}.String()
|
|
permissions := []SignedIdentifier{
|
|
{ID: "0000",
|
|
AccessPolicy: AccessPolicy{
|
|
Start: &start,
|
|
Expiry: &expiry,
|
|
Permission: &readWrite,
|
|
},
|
|
},
|
|
{ID: "0001",
|
|
AccessPolicy: AccessPolicy{
|
|
Start: &start,
|
|
Expiry: &expiry2,
|
|
Permission: &readOnly,
|
|
},
|
|
},
|
|
}
|
|
|
|
_, err := containerURL.SetAccessPolicy(ctx, PublicAccessNone, permissions,
|
|
ContainerAccessConditions{})
|
|
|
|
c.Assert(err, chk.IsNil)
|
|
|
|
resp, err := containerURL.GetAccessPolicy(ctx, LeaseAccessConditions{})
|
|
c.Assert(err, chk.IsNil)
|
|
c.Assert(resp.Items, chk.DeepEquals, permissions)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerGetPermissionsPublicAccessNotNone(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := getContainerURL(c, bsu)
|
|
containerURL.Create(ctx, nil, PublicAccessBlob) // We create the container explicitly so we can be sure the access policy is not empty
|
|
|
|
defer deleteContainer(c, containerURL)
|
|
|
|
resp, err := containerURL.GetAccessPolicy(ctx, LeaseAccessConditions{})
|
|
|
|
c.Assert(err, chk.IsNil)
|
|
c.Assert(resp.BlobPublicAccess(), chk.Equals, PublicAccessBlob)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerSetPermissionsPublicAccessNone(c *chk.C) {
|
|
// Test the basic one by making an anonymous request to ensure it's actually doing it and also with GetPermissions
|
|
// For all the others, can just use GetPermissions since we've validated that it at least registers on the server correctly
|
|
bsu := getBSU()
|
|
containerURL, containerName := createNewContainer(c, bsu)
|
|
defer deleteContainer(c, containerURL)
|
|
_, blobName := createNewBlockBlob(c, containerURL)
|
|
|
|
// Container is created with PublicAccessBlob, so setting it to None will actually test that it is changed through this method
|
|
_, err := containerURL.SetAccessPolicy(ctx, PublicAccessNone, nil, ContainerAccessConditions{})
|
|
c.Assert(err, chk.IsNil)
|
|
|
|
pipeline := NewPipeline(NewAnonymousCredential(), PipelineOptions{})
|
|
bsu2 := NewServiceURL(bsu.URL(), pipeline)
|
|
containerURL2 := bsu2.NewContainerURL(containerName)
|
|
blobURL2 := containerURL2.NewBlockBlobURL(blobName)
|
|
_, err = blobURL2.Download(ctx, 0, 0, BlobAccessConditions{}, false, ClientProvidedKeyOptions{})
|
|
|
|
// Get permissions via the original container URL so the request succeeds
|
|
resp, _ := containerURL.GetAccessPolicy(ctx, LeaseAccessConditions{})
|
|
|
|
// If we cannot access a blob's data, we will also not be able to enumerate blobs
|
|
validateStorageError(c, err, ServiceCodeNoAuthenticationInformation)
|
|
c.Assert(resp.BlobPublicAccess(), chk.Equals, PublicAccessNone)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerSetPermissionsPublicAccessBlob(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := createNewContainer(c, bsu)
|
|
|
|
defer deleteContainer(c, containerURL)
|
|
|
|
_, err := containerURL.SetAccessPolicy(ctx, PublicAccessBlob, nil, ContainerAccessConditions{})
|
|
c.Assert(err, chk.IsNil)
|
|
|
|
resp, err := containerURL.GetAccessPolicy(ctx, LeaseAccessConditions{})
|
|
c.Assert(err, chk.IsNil)
|
|
c.Assert(resp.BlobPublicAccess(), chk.Equals, PublicAccessBlob)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerSetPermissionsPublicAccessContainer(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := createNewContainer(c, bsu)
|
|
|
|
defer deleteContainer(c, containerURL)
|
|
|
|
_, err := containerURL.SetAccessPolicy(ctx, PublicAccessContainer, nil, ContainerAccessConditions{})
|
|
c.Assert(err, chk.IsNil)
|
|
|
|
resp, err := containerURL.GetAccessPolicy(ctx, LeaseAccessConditions{})
|
|
c.Assert(err, chk.IsNil)
|
|
c.Assert(resp.BlobPublicAccess(), chk.Equals, PublicAccessContainer)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerSetPermissionsACLSinglePolicy(c *chk.C) {
|
|
bsu := getBSU()
|
|
credential, err := getGenericCredential("")
|
|
if err != nil {
|
|
c.Fatal("Invalid credential")
|
|
}
|
|
containerURL, containerName := createNewContainer(c, bsu)
|
|
defer deleteContainer(c, containerURL)
|
|
_, blobName := createNewBlockBlob(c, containerURL)
|
|
|
|
start := time.Now().UTC().Add(-15 * time.Second)
|
|
expiry := start.Add(5 * time.Minute).UTC()
|
|
listOnly := AccessPolicyPermission{List: true}.String()
|
|
permissions := []SignedIdentifier{{
|
|
ID: "0000",
|
|
AccessPolicy: AccessPolicy{
|
|
Start: &start,
|
|
Expiry: &expiry,
|
|
Permission: &listOnly,
|
|
},
|
|
}}
|
|
_, err = containerURL.SetAccessPolicy(ctx, PublicAccessNone, permissions, ContainerAccessConditions{})
|
|
c.Assert(err, chk.IsNil)
|
|
|
|
serviceSASValues := BlobSASSignatureValues{Identifier: "0000", ContainerName: containerName}
|
|
queryParams, err := serviceSASValues.NewSASQueryParameters(credential)
|
|
if err != nil {
|
|
c.Fatal(err)
|
|
}
|
|
|
|
sasURL := bsu.URL()
|
|
sasURL.RawQuery = queryParams.Encode()
|
|
sasPipeline := NewPipeline(NewAnonymousCredential(), PipelineOptions{})
|
|
sasBlobServiceURL := NewServiceURL(sasURL, sasPipeline)
|
|
|
|
// Verifies that the SAS can access the resource
|
|
sasContainer := sasBlobServiceURL.NewContainerURL(containerName)
|
|
resp, err := sasContainer.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{})
|
|
c.Assert(err, chk.IsNil)
|
|
c.Assert(resp.Segment.BlobItems[0].Name, chk.Equals, blobName)
|
|
|
|
// Verifies that successful sas access is not just because it's public
|
|
anonymousBlobService := NewServiceURL(bsu.URL(), sasPipeline)
|
|
anonymousContainer := anonymousBlobService.NewContainerURL(containerName)
|
|
_, err = anonymousContainer.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{})
|
|
validateStorageError(c, err, ServiceCodeNoAuthenticationInformation)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerSetPermissionsACLMoreThanFive(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := createNewContainer(c, bsu)
|
|
|
|
defer deleteContainer(c, containerURL)
|
|
|
|
start := time.Now().UTC()
|
|
expiry := start.Add(5 * time.Minute).UTC()
|
|
permissions := make([]SignedIdentifier, 6, 6)
|
|
listOnly := AccessPolicyPermission{Read: true}.String()
|
|
for i := 0; i < 6; i++ {
|
|
permissions[i] = SignedIdentifier{
|
|
ID: "000" + strconv.Itoa(i),
|
|
AccessPolicy: AccessPolicy{
|
|
Start: &start,
|
|
Expiry: &expiry,
|
|
Permission: &listOnly,
|
|
},
|
|
}
|
|
}
|
|
|
|
_, err := containerURL.SetAccessPolicy(ctx, PublicAccessBlob, permissions, ContainerAccessConditions{})
|
|
validateStorageError(c, err, ServiceCodeInvalidXMLDocument)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerSetPermissionsDeleteAndModifyACL(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := createNewContainer(c, bsu)
|
|
|
|
defer deleteContainer(c, containerURL)
|
|
|
|
start := generateCurrentTimeWithModerateResolution()
|
|
expiry := start.Add(5 * time.Minute).UTC()
|
|
listOnly := AccessPolicyPermission{Read: true}.String()
|
|
permissions := make([]SignedIdentifier, 2, 2)
|
|
for i := 0; i < 2; i++ {
|
|
permissions[i] = SignedIdentifier{
|
|
ID: "000" + strconv.Itoa(i),
|
|
AccessPolicy: AccessPolicy{
|
|
Start: &start,
|
|
Expiry: &expiry,
|
|
Permission: &listOnly,
|
|
},
|
|
}
|
|
}
|
|
|
|
_, err := containerURL.SetAccessPolicy(ctx, PublicAccessBlob, permissions, ContainerAccessConditions{})
|
|
c.Assert(err, chk.IsNil)
|
|
|
|
resp, err := containerURL.GetAccessPolicy(ctx, LeaseAccessConditions{})
|
|
c.Assert(err, chk.IsNil)
|
|
c.Assert(resp.Items, chk.DeepEquals, permissions)
|
|
|
|
permissions = resp.Items[:1] // Delete the first policy by removing it from the slice
|
|
permissions[0].ID = "0004" // Modify the remaining policy which is at index 0 in the new slice
|
|
_, err = containerURL.SetAccessPolicy(ctx, PublicAccessBlob, permissions, ContainerAccessConditions{})
|
|
|
|
resp, err = containerURL.GetAccessPolicy(ctx, LeaseAccessConditions{})
|
|
c.Assert(err, chk.IsNil)
|
|
c.Assert(resp.Items, chk.HasLen, 1)
|
|
c.Assert(resp.Items, chk.DeepEquals, permissions)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerSetPermissionsDeleteAllPolicies(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := createNewContainer(c, bsu)
|
|
|
|
defer deleteContainer(c, containerURL)
|
|
|
|
start := time.Now().UTC()
|
|
expiry := start.Add(5 * time.Minute).UTC()
|
|
permissions := make([]SignedIdentifier, 2, 2)
|
|
listOnly := AccessPolicyPermission{Read: true}.String()
|
|
for i := 0; i < 2; i++ {
|
|
permissions[i] = SignedIdentifier{
|
|
ID: "000" + strconv.Itoa(i),
|
|
AccessPolicy: AccessPolicy{
|
|
Start: &start,
|
|
Expiry: &expiry,
|
|
Permission: &listOnly,
|
|
},
|
|
}
|
|
}
|
|
|
|
_, err := containerURL.SetAccessPolicy(ctx, PublicAccessBlob, permissions, ContainerAccessConditions{})
|
|
c.Assert(err, chk.IsNil)
|
|
|
|
_, err = containerURL.SetAccessPolicy(ctx, PublicAccessBlob, []SignedIdentifier{}, ContainerAccessConditions{})
|
|
c.Assert(err, chk.IsNil)
|
|
|
|
resp, err := containerURL.GetAccessPolicy(ctx, LeaseAccessConditions{})
|
|
c.Assert(err, chk.IsNil)
|
|
c.Assert(resp.Items, chk.HasLen, 0)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerSetPermissionsInvalidPolicyTimes(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := createNewContainer(c, bsu)
|
|
|
|
defer deleteContainer(c, containerURL)
|
|
|
|
// Swap start and expiry
|
|
expiry := time.Now().UTC()
|
|
start := expiry.Add(5 * time.Minute).UTC()
|
|
permissions := make([]SignedIdentifier, 2, 2)
|
|
listOnly := AccessPolicyPermission{Read: true}.String()
|
|
for i := 0; i < 2; i++ {
|
|
permissions[i] = SignedIdentifier{
|
|
ID: "000" + strconv.Itoa(i),
|
|
AccessPolicy: AccessPolicy{
|
|
Start: &start,
|
|
Expiry: &expiry,
|
|
Permission: &listOnly,
|
|
},
|
|
}
|
|
}
|
|
|
|
_, err := containerURL.SetAccessPolicy(ctx, PublicAccessBlob, permissions, ContainerAccessConditions{})
|
|
c.Assert(err, chk.IsNil)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerSetPermissionsNilPolicySlice(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := createNewContainer(c, bsu)
|
|
|
|
defer deleteContainer(c, containerURL)
|
|
|
|
_, err := containerURL.SetAccessPolicy(ctx, PublicAccessBlob, nil, ContainerAccessConditions{})
|
|
c.Assert(err, chk.IsNil)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerSetPermissionsSignedIdentifierTooLong(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := createNewContainer(c, bsu)
|
|
|
|
defer deleteContainer(c, containerURL)
|
|
|
|
id := ""
|
|
for i := 0; i < 65; i++ {
|
|
id += "a"
|
|
}
|
|
expiry := time.Now().UTC()
|
|
start := expiry.Add(5 * time.Minute).UTC()
|
|
permissions := make([]SignedIdentifier, 2, 2)
|
|
listOnly := AccessPolicyPermission{Read: true}.String()
|
|
for i := 0; i < 2; i++ {
|
|
permissions[i] = SignedIdentifier{
|
|
ID: id,
|
|
AccessPolicy: AccessPolicy{
|
|
Start: &start,
|
|
Expiry: &expiry,
|
|
Permission: &listOnly,
|
|
},
|
|
}
|
|
}
|
|
|
|
_, err := containerURL.SetAccessPolicy(ctx, PublicAccessBlob, permissions, ContainerAccessConditions{})
|
|
validateStorageError(c, err, ServiceCodeInvalidXMLDocument)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerSetPermissionsIfModifiedSinceTrue(c *chk.C) {
|
|
currentTime := getRelativeTimeGMT(-10)
|
|
bsu := getBSU()
|
|
container, _ := createNewContainer(c, bsu)
|
|
|
|
defer deleteContainer(c, container)
|
|
|
|
_, err := container.SetAccessPolicy(ctx, PublicAccessNone, nil,
|
|
ContainerAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}})
|
|
c.Assert(err, chk.IsNil)
|
|
|
|
resp, err := container.GetAccessPolicy(ctx, LeaseAccessConditions{})
|
|
c.Assert(err, chk.IsNil)
|
|
c.Assert(resp.BlobPublicAccess(), chk.Equals, PublicAccessNone)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerSetPermissionsIfModifiedSinceFalse(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := createNewContainer(c, bsu)
|
|
|
|
defer deleteContainer(c, containerURL)
|
|
|
|
currentTime := getRelativeTimeGMT(10)
|
|
|
|
_, err := containerURL.SetAccessPolicy(ctx, PublicAccessNone, nil,
|
|
ContainerAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}})
|
|
validateStorageError(c, err, ServiceCodeConditionNotMet)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerSetPermissionsIfUnModifiedSinceTrue(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := createNewContainer(c, bsu)
|
|
|
|
defer deleteContainer(c, containerURL)
|
|
|
|
currentTime := getRelativeTimeGMT(10)
|
|
|
|
_, err := containerURL.SetAccessPolicy(ctx, PublicAccessNone, nil,
|
|
ContainerAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}})
|
|
c.Assert(err, chk.IsNil)
|
|
|
|
resp, err := containerURL.GetAccessPolicy(ctx, LeaseAccessConditions{})
|
|
c.Assert(err, chk.IsNil)
|
|
c.Assert(resp.BlobPublicAccess(), chk.Equals, PublicAccessNone)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerSetPermissionsIfUnModifiedSinceFalse(c *chk.C) {
|
|
currentTime := getRelativeTimeGMT(-10)
|
|
|
|
bsu := getBSU()
|
|
containerURL, _ := createNewContainer(c, bsu)
|
|
|
|
defer deleteContainer(c, containerURL)
|
|
|
|
_, err := containerURL.SetAccessPolicy(ctx, PublicAccessNone, nil,
|
|
ContainerAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}})
|
|
validateStorageError(c, err, ServiceCodeConditionNotMet)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerGetPropertiesAndMetadataNoMetadata(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := createNewContainer(c, bsu)
|
|
|
|
defer deleteContainer(c, containerURL)
|
|
|
|
resp, err := containerURL.GetProperties(ctx, LeaseAccessConditions{})
|
|
c.Assert(err, chk.IsNil)
|
|
c.Assert(resp.NewMetadata(), chk.HasLen, 0)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerGetPropsAndMetaNonExistantContainer(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := getContainerURL(c, bsu)
|
|
|
|
_, err := containerURL.GetProperties(ctx, LeaseAccessConditions{})
|
|
validateStorageError(c, err, ServiceCodeContainerNotFound)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerSetMetadataEmpty(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := getContainerURL(c, bsu)
|
|
_, err := containerURL.Create(ctx, basicMetadata, PublicAccessBlob)
|
|
|
|
defer deleteContainer(c, containerURL)
|
|
|
|
_, err = containerURL.SetMetadata(ctx, Metadata{}, ContainerAccessConditions{})
|
|
c.Assert(err, chk.IsNil)
|
|
|
|
resp, err := containerURL.GetProperties(ctx, LeaseAccessConditions{})
|
|
c.Assert(err, chk.IsNil)
|
|
c.Assert(resp.NewMetadata(), chk.HasLen, 0)
|
|
}
|
|
|
|
func (*aztestsSuite) TestContainerSetMetadataNil(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := getContainerURL(c, bsu)
|
|
_, err := containerURL.Create(ctx, basicMetadata, PublicAccessBlob)
|
|
|
|
defer deleteContainer(c, containerURL)
|
|
|
|
_, err = containerURL.SetMetadata(ctx, nil, ContainerAccessConditions{})
|
|
c.Assert(err, chk.IsNil)
|
|
|
|
resp, err := containerURL.GetProperties(ctx, LeaseAccessConditions{})
|
|
c.Assert(err, chk.IsNil)
|
|
c.Assert(resp.NewMetadata(), chk.HasLen, 0)
|
|
}
|
|
|
|
func (*aztestsSuite) TestContainerSetMetadataInvalidField(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := createNewContainer(c, bsu)
|
|
|
|
defer deleteContainer(c, containerURL)
|
|
|
|
_, err := containerURL.SetMetadata(ctx, Metadata{"!nval!d Field!@#%": "value"}, ContainerAccessConditions{})
|
|
c.Assert(err, chk.NotNil)
|
|
c.Assert(strings.Contains(err.Error(), invalidHeaderErrorSubstring), chk.Equals, true)
|
|
}
|
|
|
|
func (*aztestsSuite) TestContainerSetMetadataNonExistant(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := getContainerURL(c, bsu)
|
|
|
|
_, err := containerURL.SetMetadata(ctx, nil, ContainerAccessConditions{})
|
|
validateStorageError(c, err, ServiceCodeContainerNotFound)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerSetMetadataIfModifiedSinceTrue(c *chk.C) {
|
|
currentTime := getRelativeTimeGMT(-10)
|
|
|
|
bsu := getBSU()
|
|
containerURL, _ := createNewContainer(c, bsu)
|
|
|
|
defer deleteContainer(c, containerURL)
|
|
|
|
_, err := containerURL.SetMetadata(ctx, basicMetadata,
|
|
ContainerAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}})
|
|
c.Assert(err, chk.IsNil)
|
|
|
|
resp, err := containerURL.GetProperties(ctx, LeaseAccessConditions{})
|
|
|
|
c.Assert(err, chk.IsNil)
|
|
c.Assert(resp.NewMetadata(), chk.DeepEquals, basicMetadata)
|
|
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerSetMetadataIfModifiedSinceFalse(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := createNewContainer(c, bsu)
|
|
|
|
defer deleteContainer(c, containerURL)
|
|
|
|
currentTime := getRelativeTimeGMT(10)
|
|
|
|
_, err := containerURL.SetMetadata(ctx, basicMetadata,
|
|
ContainerAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}})
|
|
|
|
validateStorageError(c, err, ServiceCodeConditionNotMet)
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerNewBlobURL(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := getContainerURL(c, bsu)
|
|
|
|
blobURL := containerURL.NewBlobURL(blobPrefix)
|
|
tempBlob := blobURL.URL()
|
|
tempContainer := containerURL.URL()
|
|
c.Assert(tempBlob.String(), chk.Equals, tempContainer.String()+"/"+blobPrefix)
|
|
c.Assert(blobURL, chk.FitsTypeOf, BlobURL{})
|
|
}
|
|
|
|
func (s *aztestsSuite) TestContainerNewBlockBlobURL(c *chk.C) {
|
|
bsu := getBSU()
|
|
containerURL, _ := getContainerURL(c, bsu)
|
|
|
|
blobURL := containerURL.NewBlockBlobURL(blobPrefix)
|
|
tempBlob := blobURL.URL()
|
|
tempContainer := containerURL.URL()
|
|
c.Assert(tempBlob.String(), chk.Equals, tempContainer.String()+"/"+blobPrefix)
|
|
c.Assert(blobURL, chk.FitsTypeOf, BlockBlobURL{})
|
|
}
|