Skip to content

Commit 653d7df

Browse files
authored
Storage/File Share test coverage improvement (Azure#4895)
* add share tests * Add accessRights test * update tests * update test records * change
1 parent f6f2617 commit 653d7df

File tree

5 files changed

+330
-1
lines changed

5 files changed

+330
-1
lines changed

sdk/storage/assets.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
"AssetsRepo": "Azure/azure-sdk-assets",
33
"AssetsRepoPrefixPath": "cpp",
44
"TagPrefix": "cpp/storage",
5-
"Tag": "cpp/storage_4491a2739b"
5+
"Tag": "cpp/storage_f900b96a8c"
66
}

sdk/storage/azure-storage-files-shares/test/ut/share_client_test.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -671,5 +671,29 @@ namespace Azure { namespace Storage { namespace Test {
671671
Files::Shares::Models::CreateSharePermissionResult created;
672672
EXPECT_NO_THROW(created = shareClient.CreatePermission(permission).Value);
673673
EXPECT_NO_THROW(shareClient.GetPermission(created.FilePermissionKey));
674+
675+
// OAuth Constructor
676+
auto shareClient1 = Files::Shares::ShareClient(
677+
m_shareClient->GetUrl(),
678+
std::make_shared<Azure::Identity::ClientSecretCredential>(
679+
AadTenantId(), AadClientId(), AadClientSecret(), GetTokenCredentialOptions()),
680+
options);
681+
EXPECT_NO_THROW(shareClient1.GetPermission(created.FilePermissionKey));
682+
}
683+
684+
TEST_F(FileShareClientTest, WithSnapshot)
685+
{
686+
const std::string timestamp1 = "2001-01-01T01:01:01.1111000Z";
687+
const std::string timestamp2 = "2022-02-02T02:02:02.2222000Z";
688+
689+
auto client1 = m_shareClient->WithSnapshot(timestamp1);
690+
EXPECT_FALSE(client1.GetUrl().find("snapshot=" + timestamp1) == std::string::npos);
691+
EXPECT_TRUE(client1.GetUrl().find("snapshot=" + timestamp2) == std::string::npos);
692+
client1 = client1.WithSnapshot(timestamp2);
693+
EXPECT_TRUE(client1.GetUrl().find("snapshot=" + timestamp1) == std::string::npos);
694+
EXPECT_FALSE(client1.GetUrl().find("snapshot=" + timestamp2) == std::string::npos);
695+
client1 = client1.WithSnapshot("");
696+
EXPECT_TRUE(client1.GetUrl().find("snapshot=" + timestamp1) == std::string::npos);
697+
EXPECT_TRUE(client1.GetUrl().find("snapshot=" + timestamp2) == std::string::npos);
674698
}
675699
}}} // namespace Azure::Storage::Test

sdk/storage/azure-storage-files-shares/test/ut/share_directory_client_test.cpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,43 @@ namespace Azure { namespace Storage { namespace Test {
2121
m_fileShareDirectoryClient->Create();
2222
}
2323

24+
TEST_F(FileShareDirectoryClientTest, Constructors)
25+
{
26+
auto clientOptions = InitStorageClientOptions<Files::Shares::ShareClientOptions>();
27+
{
28+
auto directoryClient = Files::Shares::ShareDirectoryClient::CreateFromConnectionString(
29+
StandardStorageConnectionString(), m_shareName, m_directoryName, clientOptions);
30+
EXPECT_NO_THROW(directoryClient.GetProperties());
31+
}
32+
{
33+
auto credential
34+
= _internal::ParseConnectionString(StandardStorageConnectionString()).KeyCredential;
35+
Files::Shares::ShareDirectoryClient directoryClient(
36+
m_fileShareDirectoryClient->GetUrl(), credential, clientOptions);
37+
EXPECT_NO_THROW(directoryClient.GetProperties());
38+
}
39+
{
40+
auto sasStartsOn = std::chrono::system_clock::now() - std::chrono::minutes(5);
41+
auto sasExpiresOn = std::chrono::system_clock::now() + std::chrono::minutes(60);
42+
43+
auto keyCredential
44+
= _internal::ParseConnectionString(StandardStorageConnectionString()).KeyCredential;
45+
46+
Sas::ShareSasBuilder shareSasBuilder;
47+
shareSasBuilder.Protocol = Sas::SasProtocol::HttpsAndHttp;
48+
shareSasBuilder.StartsOn = sasStartsOn;
49+
shareSasBuilder.ExpiresOn = sasExpiresOn;
50+
shareSasBuilder.ShareName = m_shareName;
51+
shareSasBuilder.Resource = Sas::ShareSasResource::Share;
52+
shareSasBuilder.SetPermissions(Sas::ShareSasPermissions::All);
53+
auto sasToken = shareSasBuilder.GenerateSasToken(*keyCredential);
54+
55+
auto directoryClient = Files::Shares::ShareDirectoryClient(
56+
m_fileShareDirectoryClient->GetUrl() + sasToken, clientOptions);
57+
EXPECT_NO_THROW(directoryClient.GetProperties());
58+
}
59+
}
60+
2461
TEST_F(FileShareDirectoryClientTest, CreateDeleteDirectories)
2562
{
2663
{
@@ -1124,6 +1161,14 @@ namespace Azure { namespace Storage { namespace Test {
11241161

11251162
// Delete
11261163
EXPECT_NO_THROW(directoryClient.Delete());
1164+
1165+
// OAuth Constructor
1166+
auto directoryClient1 = Files::Shares::ShareDirectoryClient(
1167+
m_fileShareDirectoryClient->GetUrl(),
1168+
std::make_shared<Azure::Identity::ClientSecretCredential>(
1169+
AadTenantId(), AadClientId(), AadClientSecret(), GetTokenCredentialOptions()),
1170+
options);
1171+
EXPECT_NO_THROW(directoryClient1.GetProperties());
11271172
}
11281173

11291174
// cspell:ignore myshare mydirectory
@@ -1144,4 +1189,20 @@ namespace Azure { namespace Storage { namespace Test {
11441189
EXPECT_TRUE(directoryHandles[0].AccessRights.HasValue());
11451190
EXPECT_EQ(allAccessRights, directoryHandles[0].AccessRights.Value());
11461191
}
1192+
1193+
TEST_F(FileShareDirectoryClientTest, WithShareSnapshot)
1194+
{
1195+
const std::string timestamp1 = "2001-01-01T01:01:01.1111000Z";
1196+
const std::string timestamp2 = "2022-02-02T02:02:02.2222000Z";
1197+
1198+
auto client1 = m_fileShareDirectoryClient->WithShareSnapshot(timestamp1);
1199+
EXPECT_FALSE(client1.GetUrl().find("snapshot=" + timestamp1) == std::string::npos);
1200+
EXPECT_TRUE(client1.GetUrl().find("snapshot=" + timestamp2) == std::string::npos);
1201+
client1 = client1.WithShareSnapshot(timestamp2);
1202+
EXPECT_TRUE(client1.GetUrl().find("snapshot=" + timestamp1) == std::string::npos);
1203+
EXPECT_FALSE(client1.GetUrl().find("snapshot=" + timestamp2) == std::string::npos);
1204+
client1 = client1.WithShareSnapshot("");
1205+
EXPECT_TRUE(client1.GetUrl().find("snapshot=" + timestamp1) == std::string::npos);
1206+
EXPECT_TRUE(client1.GetUrl().find("snapshot=" + timestamp2) == std::string::npos);
1207+
}
11471208
}}} // namespace Azure::Storage::Test

sdk/storage/azure-storage-files-shares/test/ut/share_file_client_test.cpp

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,30 @@ namespace Azure { namespace Storage { namespace Test {
7474
}
7575
}
7676

77+
TEST_F(FileShareFileClientTest, CreateWithHttpHeaders)
78+
{
79+
auto fileName = RandomString();
80+
Files::Shares::ShareFileClient client = m_fileShareDirectoryClient->GetFileClient(fileName);
81+
82+
std::vector<uint8_t> emptyContent;
83+
Azure::Core::Cryptography::Md5Hash instance;
84+
auto md5 = instance.Final(emptyContent.data(), 0L);
85+
86+
Files::Shares::Models::FileHttpHeaders httpHeaders;
87+
httpHeaders.ContentType = "application/x-binary";
88+
httpHeaders.ContentLanguage = "en-US";
89+
httpHeaders.ContentDisposition = "attachment";
90+
httpHeaders.CacheControl = "no-cache";
91+
httpHeaders.ContentEncoding = "identity";
92+
httpHeaders.ContentHash.Algorithm = HashAlgorithm::Md5;
93+
httpHeaders.ContentHash.Value = md5;
94+
95+
Files::Shares::CreateFileOptions options;
96+
options.HttpHeaders = httpHeaders;
97+
98+
EXPECT_NO_THROW(client.Create(1024, options));
99+
}
100+
77101
TEST_F(FileShareFileClientTest, DownloadEmptyFile)
78102
{
79103
auto fileClient = m_fileShareDirectoryClient->GetFileClient(RandomString());
@@ -656,6 +680,19 @@ namespace Azure { namespace Storage { namespace Test {
656680
EXPECT_EQ(downloadOptions.Range.Value().Offset, result.ContentRange.Offset);
657681
EXPECT_EQ(static_cast<int64_t>(numOfChunks) * rangeSize, result.FileSize);
658682
}
683+
684+
// Range download without Length
685+
{
686+
Files::Shares::DownloadFileOptions downloadOptions;
687+
downloadOptions.Range = Core::Http::HttpRange();
688+
downloadOptions.Range.Value().Offset = static_cast<int64_t>(rangeSize) * (numOfChunks - 1);
689+
Files::Shares::Models::DownloadFileResult result;
690+
EXPECT_NO_THROW(result = fileClient.Download(downloadOptions).Value);
691+
auto resultBuffer = result.BodyStream->ReadToEnd(Core::Context());
692+
EXPECT_EQ(rangeContent, resultBuffer);
693+
EXPECT_EQ(downloadOptions.Range.Value().Offset, result.ContentRange.Offset);
694+
EXPECT_EQ(static_cast<int64_t>(numOfChunks) * rangeSize, result.FileSize);
695+
}
659696
}
660697
// last write time
661698
{
@@ -703,6 +740,21 @@ namespace Azure { namespace Storage { namespace Test {
703740
uploadOptions.TransactionalContentHash = hash;
704741
memBodyStream.Rewind();
705742
EXPECT_THROW(fileClient.UploadRange(0, memBodyStream, uploadOptions), StorageException);
743+
744+
Files::Shares::DownloadFileOptions downloadOptions;
745+
downloadOptions.Range = Core::Http::HttpRange();
746+
downloadOptions.Range.Value().Offset = 0;
747+
downloadOptions.Range.Value().Length = rangeSize;
748+
downloadOptions.RangeHashAlgorithm = HashAlgorithm::Md5;
749+
Files::Shares::Models::DownloadFileResult result;
750+
EXPECT_NO_THROW(result = fileClient.Download(downloadOptions).Value);
751+
auto resultBuffer = result.BodyStream->ReadToEnd(Core::Context());
752+
EXPECT_EQ(rangeContent, resultBuffer);
753+
EXPECT_EQ(downloadOptions.Range.Value().Length.Value(), result.ContentRange.Length.Value());
754+
EXPECT_EQ(downloadOptions.Range.Value().Offset, result.ContentRange.Offset);
755+
EXPECT_EQ(static_cast<int64_t>(numOfChunks) * rangeSize, result.FileSize);
756+
EXPECT_TRUE(result.TransactionalContentHash.HasValue());
757+
EXPECT_EQ(md5, result.TransactionalContentHash.Value().Value);
706758
}
707759
}
708760

@@ -736,6 +788,37 @@ namespace Azure { namespace Storage { namespace Test {
736788
}
737789
}
738790

791+
TEST_F(FileShareFileClientTest, CopyWithProperties)
792+
{
793+
size_t fileSize = 128;
794+
std::vector<uint8_t> fileContent = RandomBuffer(fileSize);
795+
auto memBodyStream = Core::IO::MemoryBodyStream(fileContent);
796+
{
797+
// Simple copy works.
798+
auto fileClient = m_shareClient->GetRootDirectoryClient().GetFileClient(RandomString() + "1");
799+
fileClient.Create(fileSize);
800+
801+
auto sourceProperties = fileClient.GetProperties().Value;
802+
803+
Files::Shares::StartFileCopyOptions options;
804+
options.SmbProperties.Attributes = sourceProperties.SmbProperties.Attributes;
805+
options.SmbProperties.CreatedOn = sourceProperties.SmbProperties.CreatedOn;
806+
options.SmbProperties.ChangedOn = sourceProperties.SmbProperties.ChangedOn;
807+
options.SmbProperties.LastWrittenOn = sourceProperties.SmbProperties.LastWrittenOn;
808+
options.PermissionCopyMode = Files::Shares::Models::PermissionCopyMode::Override;
809+
options.SmbProperties.PermissionKey = sourceProperties.SmbProperties.PermissionKey;
810+
811+
auto destFileClient
812+
= m_shareClient->GetRootDirectoryClient().GetFileClient(RandomString() + "2");
813+
auto copyOperation = destFileClient.StartCopy(fileClient.GetUrl(), options);
814+
EXPECT_EQ(
815+
copyOperation.GetRawResponse().GetStatusCode(),
816+
Azure::Core::Http::HttpStatusCode::Accepted);
817+
auto fileProperties = copyOperation.PollUntilDone(std::chrono::milliseconds(1000)).Value;
818+
EXPECT_EQ(fileProperties.CopyStatus.Value(), Files::Shares::Models::CopyStatus::Success);
819+
}
820+
}
821+
739822
TEST_F(FileShareFileClientTest, RangeRelated)
740823
{
741824
size_t fileSize = 1024 * 3;
@@ -764,6 +847,60 @@ namespace Azure { namespace Storage { namespace Test {
764847
EXPECT_EQ(static_cast<int32_t>(fileSize / 2) - 1024, result.Ranges[1].Length.Value());
765848
}
766849

850+
TEST_F(FileShareFileClientTest, GetRangeListWithRange)
851+
{
852+
size_t rangeSize = 128;
853+
std::vector<uint8_t> rangeContent = RandomBuffer(rangeSize);
854+
auto memBodyStream = Core::IO::MemoryBodyStream(rangeContent);
855+
856+
auto fileClient = m_shareClient->GetRootDirectoryClient().GetFileClient(RandomString());
857+
fileClient.Create(rangeSize);
858+
859+
EXPECT_NO_THROW(fileClient.UploadRange(0, memBodyStream));
860+
861+
// GetRangeList with Range
862+
{
863+
Files::Shares::GetFileRangeListOptions options;
864+
options.Range = Core::Http::HttpRange();
865+
options.Range.Value().Offset = 0;
866+
options.Range.Value().Length = 128;
867+
Files::Shares::Models::GetFileRangeListResult result;
868+
869+
EXPECT_NO_THROW(result = fileClient.GetRangeList(options).Value);
870+
EXPECT_EQ(1U, result.Ranges.size());
871+
EXPECT_EQ(0, result.Ranges[0].Offset);
872+
EXPECT_TRUE(result.Ranges[0].Length.HasValue());
873+
874+
options.Range.Value().Length.Reset();
875+
EXPECT_NO_THROW(result = fileClient.GetRangeList(options).Value);
876+
EXPECT_EQ(1U, result.Ranges.size());
877+
EXPECT_EQ(0, result.Ranges[0].Offset);
878+
EXPECT_TRUE(result.Ranges[0].Length.HasValue());
879+
}
880+
881+
// GetRangeListDiff with Range
882+
{
883+
auto snapshot = m_shareClient->CreateSnapshot().Value.Snapshot;
884+
EXPECT_NO_THROW(fileClient.ClearRange(64, 64));
885+
Files::Shares::GetFileRangeListOptions options;
886+
options.Range = Core::Http::HttpRange();
887+
options.Range.Value().Offset = 64;
888+
options.Range.Value().Length = 64;
889+
Files::Shares::Models::GetFileRangeListResult result;
890+
891+
EXPECT_NO_THROW(result = fileClient.GetRangeListDiff(snapshot, options).Value);
892+
EXPECT_EQ(1U, result.Ranges.size());
893+
EXPECT_EQ(64, result.Ranges[0].Offset);
894+
EXPECT_TRUE(result.Ranges[0].Length.HasValue());
895+
896+
options.Range.Value().Length.Reset();
897+
EXPECT_NO_THROW(result = fileClient.GetRangeListDiff(snapshot, options).Value);
898+
EXPECT_EQ(1U, result.Ranges.size());
899+
EXPECT_EQ(64, result.Ranges[0].Offset);
900+
EXPECT_TRUE(result.Ranges[0].Length.HasValue());
901+
}
902+
}
903+
767904
TEST_F(FileShareFileClientTest, PreviousRangeWithSnapshot)
768905
{
769906
size_t fileSize = 1024 * 10;
@@ -1084,6 +1221,40 @@ namespace Azure { namespace Storage { namespace Test {
10841221
EXPECT_NO_THROW(containerClient.Delete());
10851222
}
10861223

1224+
TEST_F(FileShareFileClientTest, UploadFromWithOptions)
1225+
{
1226+
auto fileClient = m_shareClient->GetRootDirectoryClient().GetFileClient(RandomString());
1227+
1228+
size_t fileSize = 512;
1229+
std::vector<uint8_t> content(RandomBuffer(fileSize));
1230+
auto memBodyStream = Core::IO::MemoryBodyStream(content);
1231+
1232+
Azure::Core::Cryptography::Md5Hash instance;
1233+
auto md5 = instance.Final(content.data(), fileSize);
1234+
1235+
Files::Shares::UploadFileFromOptions options;
1236+
1237+
options.SmbProperties.Attributes = Files::Shares::Models::FileAttributes::Hidden;
1238+
options.SmbProperties.CreatedOn = std::chrono::system_clock::now();
1239+
options.SmbProperties.LastWrittenOn = std::chrono::system_clock::now();
1240+
options.SmbProperties.PermissionKey = "";
1241+
options.SmbProperties.ChangedOn = std::chrono::system_clock::now();
1242+
options.HttpHeaders.ContentType = "application/x-binary";
1243+
options.HttpHeaders.ContentLanguage = "en-US";
1244+
options.HttpHeaders.ContentDisposition = "attachment";
1245+
options.HttpHeaders.CacheControl = "no-cache";
1246+
options.HttpHeaders.ContentEncoding = "identity";
1247+
options.HttpHeaders.ContentHash.Value = md5;
1248+
1249+
// UploadFrom buffer
1250+
EXPECT_NO_THROW(fileClient.UploadFrom(content.data(), fileSize, options));
1251+
1252+
// UploadFrom file
1253+
const std::string tempFilename = "file" + RandomString();
1254+
WriteFile(tempFilename, content);
1255+
EXPECT_NO_THROW(fileClient.UploadFrom(tempFilename, options));
1256+
}
1257+
10871258
TEST_F(FileShareFileClientTest, AllowTrailingDot)
10881259
{
10891260
const std::string fileName = RandomString();
@@ -1430,6 +1601,14 @@ namespace Azure { namespace Storage { namespace Test {
14301601

14311602
// Delete
14321603
EXPECT_NO_THROW(fileClient.Delete());
1604+
1605+
// OAuth Constructor
1606+
auto fileClient1 = Files::Shares::ShareFileClient(
1607+
m_fileClient->GetUrl(),
1608+
std::make_shared<Azure::Identity::ClientSecretCredential>(
1609+
AadTenantId(), AadClientId(), AadClientSecret(), GetTokenCredentialOptions()),
1610+
options);
1611+
EXPECT_NO_THROW(fileClient1.GetProperties());
14331612
}
14341613

14351614
TEST_F(FileShareFileClientTest, OAuthCopy_PLAYBACKONLY_)
@@ -1496,4 +1675,44 @@ namespace Azure { namespace Storage { namespace Test {
14961675
EXPECT_TRUE(fileHandles[0].AccessRights.HasValue());
14971676
EXPECT_EQ(allAccessRights, fileHandles[0].AccessRights.Value());
14981677
}
1678+
1679+
TEST_F(FileShareFileClientTest, WithShareSnapshot)
1680+
{
1681+
const std::string timestamp1 = "2001-01-01T01:01:01.1111000Z";
1682+
const std::string timestamp2 = "2022-02-02T02:02:02.2222000Z";
1683+
1684+
auto client1 = m_fileClient->WithShareSnapshot(timestamp1);
1685+
EXPECT_FALSE(client1.GetUrl().find("snapshot=" + timestamp1) == std::string::npos);
1686+
EXPECT_TRUE(client1.GetUrl().find("snapshot=" + timestamp2) == std::string::npos);
1687+
client1 = client1.WithShareSnapshot(timestamp2);
1688+
EXPECT_TRUE(client1.GetUrl().find("snapshot=" + timestamp1) == std::string::npos);
1689+
EXPECT_FALSE(client1.GetUrl().find("snapshot=" + timestamp2) == std::string::npos);
1690+
client1 = client1.WithShareSnapshot("");
1691+
EXPECT_TRUE(client1.GetUrl().find("snapshot=" + timestamp1) == std::string::npos);
1692+
EXPECT_TRUE(client1.GetUrl().find("snapshot=" + timestamp2) == std::string::npos);
1693+
}
1694+
1695+
TEST(ShareFileHandleAccessRightsTest, ShareFileHandleAccessRights)
1696+
{
1697+
Files::Shares::Models::ShareFileHandleAccessRights accessRightsA
1698+
= Files::Shares::Models::ShareFileHandleAccessRights::Read
1699+
| Files::Shares::Models::ShareFileHandleAccessRights::Write;
1700+
Files::Shares::Models::ShareFileHandleAccessRights accessRightsB
1701+
= Files::Shares::Models::ShareFileHandleAccessRights::Write
1702+
| Files::Shares::Models::ShareFileHandleAccessRights::Delete;
1703+
1704+
Files::Shares::Models::ShareFileHandleAccessRights orAccessRights
1705+
= Files::Shares::Models::ShareFileHandleAccessRights::Read
1706+
| Files::Shares::Models::ShareFileHandleAccessRights::Write
1707+
| Files::Shares::Models::ShareFileHandleAccessRights::Delete;
1708+
Files::Shares::Models::ShareFileHandleAccessRights andAccessRights
1709+
= Files::Shares::Models::ShareFileHandleAccessRights::Write;
1710+
Files::Shares::Models::ShareFileHandleAccessRights xorAccessRights
1711+
= Files::Shares::Models::ShareFileHandleAccessRights::Read
1712+
| Files::Shares::Models::ShareFileHandleAccessRights::Delete;
1713+
1714+
EXPECT_EQ(orAccessRights, accessRightsA | accessRightsB);
1715+
EXPECT_EQ(andAccessRights, accessRightsA & accessRightsB);
1716+
EXPECT_EQ(xorAccessRights, accessRightsA ^ accessRightsB);
1717+
}
14991718
}}} // namespace Azure::Storage::Test

0 commit comments

Comments
 (0)