Improve storage blob & queue coverage (#4888)

This commit is contained in:
JinmingHu 2023-08-17 10:15:56 +08:00 committed by GitHub
parent 25f33e9800
commit 7c10104461
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 396 additions and 4 deletions

View File

@ -2,5 +2,5 @@
"AssetsRepo": "Azure/azure-sdk-assets",
"AssetsRepoPrefixPath": "cpp",
"TagPrefix": "cpp/storage",
"Tag": "cpp/storage_d4662c63f9"
"Tag": "cpp/storage_ee4c1bee4d"
}

View File

@ -36,7 +36,55 @@ namespace Azure { namespace Storage { namespace Test {
m_blobContent.insert(m_blobContent.end(), blobContent2.begin(), blobContent2.end());
}
// Requires blob versioning?
TEST_F(AppendBlobClientTest, Constructors)
{
auto clientOptions = InitStorageClientOptions<Blobs::BlobClientOptions>();
{
auto appendBlobClient = Blobs::AppendBlobClient::CreateFromConnectionString(
StandardStorageConnectionString(), m_containerName, m_blobName, clientOptions);
EXPECT_NO_THROW(appendBlobClient.GetProperties());
}
{
auto cred = _internal::ParseConnectionString(StandardStorageConnectionString()).KeyCredential;
auto appendBlobClient
= Blobs::AppendBlobClient(m_appendBlobClient->GetUrl(), cred, clientOptions);
EXPECT_NO_THROW(appendBlobClient.GetProperties());
}
{
auto appendBlobClient
= Blobs::AppendBlobClient(m_appendBlobClient->GetUrl() + GetSas(), clientOptions);
EXPECT_NO_THROW(appendBlobClient.GetProperties());
}
}
TEST_F(AppendBlobClientTest, WithSnapshotVersionId)
{
const std::string timestamp1 = "2001-01-01T01:01:01.1111000Z";
const std::string timestamp2 = "2022-02-02T02:02:02.2222000Z";
auto client1 = m_appendBlobClient->WithSnapshot(timestamp1);
EXPECT_FALSE(client1.GetUrl().find("snapshot=" + timestamp1) == std::string::npos);
EXPECT_TRUE(client1.GetUrl().find("snapshot=" + timestamp2) == std::string::npos);
client1 = client1.WithSnapshot(timestamp2);
EXPECT_TRUE(client1.GetUrl().find("snapshot=" + timestamp1) == std::string::npos);
EXPECT_FALSE(client1.GetUrl().find("snapshot=" + timestamp2) == std::string::npos);
client1 = client1.WithSnapshot("");
EXPECT_TRUE(client1.GetUrl().find("snapshot=" + timestamp1) == std::string::npos);
EXPECT_TRUE(client1.GetUrl().find("snapshot=" + timestamp2) == std::string::npos);
client1 = m_appendBlobClient->WithVersionId(timestamp1);
EXPECT_FALSE(client1.GetUrl().find("versionid=" + timestamp1) == std::string::npos);
EXPECT_TRUE(client1.GetUrl().find("versionid=" + timestamp2) == std::string::npos);
client1 = client1.WithVersionId(timestamp2);
EXPECT_TRUE(client1.GetUrl().find("versionid=" + timestamp1) == std::string::npos);
EXPECT_FALSE(client1.GetUrl().find("versionid=" + timestamp2) == std::string::npos);
client1 = client1.WithVersionId("");
EXPECT_TRUE(client1.GetUrl().find("versionid=" + timestamp1) == std::string::npos);
EXPECT_TRUE(client1.GetUrl().find("versionid=" + timestamp2) == std::string::npos);
}
TEST_F(AppendBlobClientTest, CreateAppendDelete)
{
auto blobClient = *m_appendBlobClient;
@ -329,6 +377,36 @@ namespace Azure { namespace Storage { namespace Test {
appendBlobClient2.AppendBlockFromUri(appendBlobClient.GetUrl() + GetSas(), options2));
}
TEST_F(AppendBlobClientTest, AppendBlockFromUriRange)
{
auto appendBlobClient = GetAppendBlobClientForTest(RandomString());
const std::vector<uint8_t> blobContent = RandomBuffer(10);
appendBlobClient.Create();
auto contentStream = Azure::Core::IO::MemoryBodyStream(blobContent.data(), blobContent.size());
appendBlobClient.AppendBlock(contentStream);
auto appendBlobClient2 = GetAppendBlobClientForTest(RandomString());
appendBlobClient2.Create();
Blobs::AppendBlockFromUriOptions options;
options.SourceRange = Azure::Core::Http::HttpRange();
options.SourceRange.Value().Offset = 5;
options.SourceRange.Value().Length = 5;
EXPECT_NO_THROW(
appendBlobClient2.AppendBlockFromUri(appendBlobClient.GetUrl() + GetSas(), options));
auto downloadContent = appendBlobClient2.Download().Value.BodyStream->ReadToEnd();
EXPECT_EQ(
downloadContent.size(), static_cast<size_t>(options.SourceRange.Value().Length.Value()));
EXPECT_EQ(
downloadContent,
std::vector<uint8_t>(
blobContent.begin() + static_cast<size_t>(options.SourceRange.Value().Offset),
blobContent.end()));
}
TEST_F(AppendBlobClientTest, DISABLED_AppendBlockFromUriCrc64AccessCondition)
{
auto appendBlobClient = GetAppendBlobClientForTest(RandomString());

View File

@ -7,7 +7,7 @@
namespace Azure { namespace Storage { namespace Test {
TEST_F(BlobContainerClientTest, BatchSubmitDelete_LIVEONLY_)
TEST_F(BlobContainerClientTest, ServiceBatchSubmitDelete_LIVEONLY_)
{
const std::string containerNamePrefix = LowercaseRandomString();
@ -46,6 +46,38 @@ namespace Azure { namespace Storage { namespace Test {
EXPECT_NO_THROW(blob3Client.GetProperties());
}
TEST_F(BlobContainerClientTest, ContainerBatchSubmitDelete_LIVEONLY_)
{
auto containerClient = *m_blobContainerClient;
const std::string blob1Name = "b1";
const std::string blob2Name = "b2";
const std::string blob3Name = "b3";
auto blob1Client = containerClient.GetAppendBlobClient(blob1Name);
blob1Client.Create();
auto blob2Client = containerClient.GetAppendBlobClient(blob2Name);
blob2Client.Create();
auto blob3Client = containerClient.GetAppendBlobClient(blob3Name);
blob3Client.Create();
blob3Client.CreateSnapshot();
auto batch = containerClient.CreateBatch();
auto delete1Response = batch.DeleteBlobUrl(blob1Client.GetUrl());
auto delete2Response = batch.DeleteBlob(blob2Name);
Blobs::DeleteBlobOptions deleteOptions;
deleteOptions.DeleteSnapshots = Blobs::Models::DeleteSnapshotsOption::OnlySnapshots;
auto delete3Response = batch.DeleteBlobUrl(blob3Client.GetUrl(), deleteOptions);
auto submitBatchResponse = containerClient.SubmitBatch(batch);
EXPECT_TRUE(delete1Response.GetResponse().Value.Deleted);
EXPECT_TRUE(delete2Response.GetResponse().Value.Deleted);
EXPECT_TRUE(delete3Response.GetResponse().Value.Deleted);
EXPECT_THROW(blob1Client.GetProperties(), StorageException);
EXPECT_THROW(blob2Client.GetProperties(), StorageException);
EXPECT_NO_THROW(blob3Client.GetProperties());
}
TEST_F(BlobContainerClientTest, BatchSnapshotVersion_LIVEONLY_)
{
const std::string containerNamePrefix = LowercaseRandomString();
@ -87,7 +119,7 @@ namespace Azure { namespace Storage { namespace Test {
EXPECT_THROW(blob1Client.WithSnapshot(snapshotId).GetProperties(), StorageException);
}
TEST_F(BlobContainerClientTest, BatchSubmitSetTier_LIVEONLY_)
TEST_F(BlobContainerClientTest, ServiceBatchSubmitSetTier_LIVEONLY_)
{
const std::string containerName = LowercaseRandomString();
const std::string blob1Name = "b1";
@ -129,6 +161,32 @@ namespace Azure { namespace Storage { namespace Test {
blob2Client.GetProperties().Value.AccessTier.Value(), Blobs::Models::AccessTier::Archive);
}
TEST_F(BlobContainerClientTest, ContainerBatchSubmitSetTier_LIVEONLY_)
{
const std::string blob1Name = "b1";
const std::string blob2Name = "b2";
auto containerClient = *m_blobContainerClient;
auto blob1Client = containerClient.GetBlockBlobClient(blob1Name);
blob1Client.UploadFrom(nullptr, 0);
auto blob2Client = containerClient.GetBlockBlobClient(blob2Name);
blob2Client.UploadFrom(nullptr, 0);
auto batch = containerClient.CreateBatch();
auto setTier1Response
= batch.SetBlobAccessTierUrl(blob1Client.GetUrl(), Blobs::Models::AccessTier::Cool);
auto setTier2Response = batch.SetBlobAccessTier(blob2Name, Blobs::Models::AccessTier::Archive);
auto submitBatchResponse = containerClient.SubmitBatch(batch);
EXPECT_NO_THROW(setTier1Response.GetResponse());
EXPECT_NO_THROW(setTier2Response.GetResponse());
EXPECT_EQ(
blob1Client.GetProperties().Value.AccessTier.Value(), Blobs::Models::AccessTier::Cool);
EXPECT_EQ(
blob2Client.GetProperties().Value.AccessTier.Value(), Blobs::Models::AccessTier::Archive);
}
TEST_F(BlobContainerClientTest, BatchTokenAuthorization_LIVEONLY_)
{
std::shared_ptr<Azure::Core::Credentials::TokenCredential> credential

View File

@ -167,6 +167,19 @@ namespace Azure { namespace Storage { namespace Test {
EXPECT_TRUE(properties.Metadata.empty());
}
TEST_F(BlobContainerClientTest, UploadDeleteConvenientMethods)
{
auto containerClient = *m_blobContainerClient;
auto blobName = RandomString();
auto blobContent = RandomBuffer(static_cast<size_t>(10));
auto blobContentStream
= Azure::Core::IO::MemoryBodyStream(blobContent.data(), blobContent.size());
EXPECT_NO_THROW(containerClient.UploadBlob(blobName, blobContentStream));
EXPECT_NO_THROW(containerClient.GetBlobClient(blobName).GetProperties());
EXPECT_NO_THROW(containerClient.DeleteBlob(blobName));
EXPECT_THROW(containerClient.GetBlobClient(blobName).GetProperties(), StorageException);
}
TEST_F(BlobContainerClientTest, ListBlobsFlat)
{
auto containerClient = *m_blobContainerClient;

View File

@ -56,6 +56,55 @@ namespace Azure { namespace Storage { namespace Test {
= m_blockBlobClient->GetProperties().Value.HttpHeaders.ContentHash;
}
TEST_F(BlockBlobClientTest, Constructors)
{
auto clientOptions = InitStorageClientOptions<Blobs::BlobClientOptions>();
{
auto blockBlobClient = Blobs::BlockBlobClient::CreateFromConnectionString(
StandardStorageConnectionString(), m_containerName, m_blobName, clientOptions);
EXPECT_NO_THROW(blockBlobClient.GetProperties());
}
{
auto cred = _internal::ParseConnectionString(StandardStorageConnectionString()).KeyCredential;
auto blockBlobClient
= Blobs::BlockBlobClient(m_blockBlobClient->GetUrl(), cred, clientOptions);
EXPECT_NO_THROW(blockBlobClient.GetProperties());
}
{
auto blockBlobClient
= Blobs::BlockBlobClient(m_blockBlobClient->GetUrl() + GetSas(), clientOptions);
EXPECT_NO_THROW(blockBlobClient.GetProperties());
}
}
TEST_F(BlockBlobClientTest, WithSnapshotVersionId)
{
const std::string timestamp1 = "2001-01-01T01:01:01.1111000Z";
const std::string timestamp2 = "2022-02-02T02:02:02.2222000Z";
auto client1 = m_blockBlobClient->WithSnapshot(timestamp1);
EXPECT_FALSE(client1.GetUrl().find("snapshot=" + timestamp1) == std::string::npos);
EXPECT_TRUE(client1.GetUrl().find("snapshot=" + timestamp2) == std::string::npos);
client1 = client1.WithSnapshot(timestamp2);
EXPECT_TRUE(client1.GetUrl().find("snapshot=" + timestamp1) == std::string::npos);
EXPECT_FALSE(client1.GetUrl().find("snapshot=" + timestamp2) == std::string::npos);
client1 = client1.WithSnapshot("");
EXPECT_TRUE(client1.GetUrl().find("snapshot=" + timestamp1) == std::string::npos);
EXPECT_TRUE(client1.GetUrl().find("snapshot=" + timestamp2) == std::string::npos);
client1 = m_blockBlobClient->WithVersionId(timestamp1);
EXPECT_FALSE(client1.GetUrl().find("versionid=" + timestamp1) == std::string::npos);
EXPECT_TRUE(client1.GetUrl().find("versionid=" + timestamp2) == std::string::npos);
client1 = client1.WithVersionId(timestamp2);
EXPECT_TRUE(client1.GetUrl().find("versionid=" + timestamp1) == std::string::npos);
EXPECT_FALSE(client1.GetUrl().find("versionid=" + timestamp2) == std::string::npos);
client1 = client1.WithVersionId("");
EXPECT_TRUE(client1.GetUrl().find("versionid=" + timestamp1) == std::string::npos);
EXPECT_TRUE(client1.GetUrl().find("versionid=" + timestamp2) == std::string::npos);
}
TEST_F(BlockBlobClientTest, CreateDelete)
{
auto blobClient = *m_blockBlobClient;
@ -756,6 +805,26 @@ namespace Azure { namespace Storage { namespace Test {
EXPECT_TRUE(res.Value.UncommittedBlocks.empty());
}
TEST_F(BlockBlobClientTest, StageBlockFromUriRange)
{
auto srcBlobClient = *m_blockBlobClient;
auto destClient = GetBlockBlobClientForTest(RandomString());
const std::string blockId1 = Base64EncodeText("0");
Storage::Blobs::StageBlockFromUriOptions options;
options.SourceRange = Core::Http::HttpRange();
options.SourceRange.Value().Offset = 1;
options.SourceRange.Value().Length = 2;
destClient.StageBlockFromUri(blockId1, srcBlobClient.GetUrl() + GetSas(), options);
Blobs::GetBlockListOptions options2;
options2.ListType = Blobs::Models::BlockListType::All;
auto blocks = destClient.GetBlockList(options2).Value.UncommittedBlocks;
ASSERT_FALSE(blocks.empty());
EXPECT_EQ(blocks[0].Name, blockId1);
EXPECT_EQ(blocks[0].Size, 2);
}
TEST_F(BlockBlobClientTest, OAuthStageBlockFromUri)
{
auto srcBlobClient = *m_blockBlobClient;
@ -1914,4 +1983,22 @@ namespace Azure { namespace Storage { namespace Test {
}
}
TEST_F(BlockBlobClientTest, MaxUploadBlockSize)
{
#ifdef _WIN64
auto blobClient = *m_blockBlobClient;
Blobs::UploadBlockBlobFromOptions options;
try
{
blobClient.UploadFrom(reinterpret_cast<const uint8_t*>("a"), 300_TB, options);
FAIL();
}
catch (Azure::Core::RequestFailedException& e)
{
EXPECT_STREQ(e.what(), "Block size is too big.");
}
#endif
}
}}} // namespace Azure::Storage::Test

View File

@ -37,6 +37,54 @@ namespace Azure { namespace Storage { namespace Test {
m_blobContent.resize(static_cast<size_t>(2_KB));
}
TEST_F(PageBlobClientTest, Constructors)
{
auto clientOptions = InitStorageClientOptions<Blobs::BlobClientOptions>();
{
auto pageBlobClient = Blobs::PageBlobClient::CreateFromConnectionString(
StandardStorageConnectionString(), m_containerName, m_blobName, clientOptions);
EXPECT_NO_THROW(pageBlobClient.GetProperties());
}
{
auto cred = _internal::ParseConnectionString(StandardStorageConnectionString()).KeyCredential;
auto pageBlobClient = Blobs::PageBlobClient(m_pageBlobClient->GetUrl(), cred, clientOptions);
EXPECT_NO_THROW(pageBlobClient.GetProperties());
}
{
auto pageBlobClient
= Blobs::PageBlobClient(m_pageBlobClient->GetUrl() + GetSas(), clientOptions);
EXPECT_NO_THROW(pageBlobClient.GetProperties());
}
}
TEST_F(PageBlobClientTest, WithSnapshotVersionId)
{
const std::string timestamp1 = "2001-01-01T01:01:01.1111000Z";
const std::string timestamp2 = "2022-02-02T02:02:02.2222000Z";
auto client1 = m_pageBlobClient->WithSnapshot(timestamp1);
EXPECT_FALSE(client1.GetUrl().find("snapshot=" + timestamp1) == std::string::npos);
EXPECT_TRUE(client1.GetUrl().find("snapshot=" + timestamp2) == std::string::npos);
client1 = client1.WithSnapshot(timestamp2);
EXPECT_TRUE(client1.GetUrl().find("snapshot=" + timestamp1) == std::string::npos);
EXPECT_FALSE(client1.GetUrl().find("snapshot=" + timestamp2) == std::string::npos);
client1 = client1.WithSnapshot("");
EXPECT_TRUE(client1.GetUrl().find("snapshot=" + timestamp1) == std::string::npos);
EXPECT_TRUE(client1.GetUrl().find("snapshot=" + timestamp2) == std::string::npos);
client1 = m_pageBlobClient->WithVersionId(timestamp1);
EXPECT_FALSE(client1.GetUrl().find("versionid=" + timestamp1) == std::string::npos);
EXPECT_TRUE(client1.GetUrl().find("versionid=" + timestamp2) == std::string::npos);
client1 = client1.WithVersionId(timestamp2);
EXPECT_TRUE(client1.GetUrl().find("versionid=" + timestamp1) == std::string::npos);
EXPECT_FALSE(client1.GetUrl().find("versionid=" + timestamp2) == std::string::npos);
client1 = client1.WithVersionId("");
EXPECT_TRUE(client1.GetUrl().find("versionid=" + timestamp1) == std::string::npos);
EXPECT_TRUE(client1.GetUrl().find("versionid=" + timestamp2) == std::string::npos);
}
TEST_F(PageBlobClientTest, CreateDelete)
{
auto pageBlobClient = *m_pageBlobClient;
@ -198,12 +246,26 @@ namespace Azure { namespace Storage { namespace Test {
Blobs::GetPageRangesOptions options;
options.PageSizeHint = 1;
int numPages = 0;
int numItems = 0;
for (auto page = pageBlobClient.GetPageRangesDiff(snapshot, options); page.HasPage();
page.MoveToNextPage())
{
++numPages;
numItems += static_cast<int>(page.PageRanges.size() + page.ClearRanges.size());
}
EXPECT_GT(numPages, 2);
EXPECT_EQ(numItems, 3);
// range
numItems = 0;
options.Range = Core::Http::HttpRange();
options.Range.Value().Offset = 1024 * 2;
for (auto page = pageBlobClient.GetPageRangesDiff(snapshot, options); page.HasPage();
page.MoveToNextPage())
{
numItems += static_cast<int>(page.PageRanges.size() + page.ClearRanges.size());
}
EXPECT_EQ(numItems, 1);
}
TEST_F(PageBlobClientTest, UploadFromUri)

View File

@ -39,6 +39,22 @@ namespace Azure { namespace Storage { namespace Test {
m_fileClient->CreateIfNotExists();
}
TEST_F(DataLakeFileClientTest, BlobUndelete)
{
auto containerName = m_fileSystemName;
auto blobName = m_fileName;
auto blobClient = Blobs::BlobClient::CreateFromConnectionString(
AdlsGen2ConnectionString(),
containerName,
blobName,
InitStorageClientOptions<Blobs::BlobClientOptions>());
EXPECT_NO_THROW(blobClient.GetProperties());
blobClient.Delete();
EXPECT_THROW(blobClient.GetProperties(), StorageException);
blobClient.Undelete();
EXPECT_NO_THROW(blobClient.GetProperties());
}
TEST_F(DataLakeFileClientTest, CreateDeleteFiles)
{
{

View File

@ -71,6 +71,44 @@ namespace Azure { namespace Storage { namespace Test {
return queueClient;
}
TEST_F(QueueClientTest, Constructors)
{
auto keyCredential
= _internal::ParseConnectionString(StandardStorageConnectionString()).KeyCredential;
auto getSas = [&]() {
auto sasStartsOn = std::chrono::system_clock::now() - std::chrono::minutes(5);
auto sasExpiresOn = std::chrono::system_clock::now() + std::chrono::minutes(60);
Sas::AccountSasBuilder accountSasBuilder;
accountSasBuilder.Protocol = Sas::SasProtocol::HttpsAndHttp;
accountSasBuilder.StartsOn = sasStartsOn;
accountSasBuilder.ExpiresOn = sasExpiresOn;
accountSasBuilder.Services = Sas::AccountSasServices::Queue;
accountSasBuilder.ResourceTypes = Sas::AccountSasResource::All;
accountSasBuilder.SetPermissions(Sas::AccountSasPermissions::Read);
auto sasToken = accountSasBuilder.GenerateSasToken(*keyCredential);
return sasToken;
};
auto clientOptions = InitStorageClientOptions<Queues::QueueClientOptions>();
{
auto queueClient = Queues::QueueClient::CreateFromConnectionString(
StandardStorageConnectionString(), m_queueName, clientOptions);
EXPECT_NO_THROW(queueClient.GetProperties());
}
{
auto queueClient = Queues::QueueClient(m_queueClient->GetUrl(), keyCredential, clientOptions);
EXPECT_NO_THROW(queueClient.GetProperties());
}
{
auto queueClient = Queues::QueueClient(m_queueClient->GetUrl() + getSas(), clientOptions);
EXPECT_NO_THROW(queueClient.GetProperties());
}
}
TEST_F(QueueClientTest, CreateDelete)
{
auto queueClient = GetQueueClientForTest(LowercaseRandomString());

View File

@ -54,6 +54,46 @@ namespace Azure { namespace Storage { namespace Test {
Queues::QueueClientOptions m_options;
};
TEST_F(QueueServiceClientTest, Constructors)
{
auto keyCredential
= _internal::ParseConnectionString(StandardStorageConnectionString()).KeyCredential;
auto getSas = [&]() {
auto sasStartsOn = std::chrono::system_clock::now() - std::chrono::minutes(5);
auto sasExpiresOn = std::chrono::system_clock::now() + std::chrono::minutes(60);
Sas::AccountSasBuilder accountSasBuilder;
accountSasBuilder.Protocol = Sas::SasProtocol::HttpsAndHttp;
accountSasBuilder.StartsOn = sasStartsOn;
accountSasBuilder.ExpiresOn = sasExpiresOn;
accountSasBuilder.Services = Sas::AccountSasServices::Queue;
accountSasBuilder.ResourceTypes = Sas::AccountSasResource::All;
accountSasBuilder.SetPermissions(Sas::AccountSasPermissions::Read);
auto sasToken = accountSasBuilder.GenerateSasToken(*keyCredential);
return sasToken;
};
auto clientOptions = InitStorageClientOptions<Queues::QueueClientOptions>();
{
auto queueClient = Queues::QueueServiceClient::CreateFromConnectionString(
StandardStorageConnectionString(), clientOptions);
EXPECT_NO_THROW(queueClient.GetProperties());
}
{
auto queueClient = Queues::QueueServiceClient(
m_queueServiceClient->GetUrl(), keyCredential, clientOptions);
EXPECT_NO_THROW(queueClient.GetProperties());
}
{
auto queueClient
= Queues::QueueServiceClient(m_queueServiceClient->GetUrl() + getSas(), clientOptions);
EXPECT_NO_THROW(queueClient.GetProperties());
}
}
TEST_F(QueueServiceClientTest, ListQueues)
{
const std::string prefix1 = "prefix1-a-";