diff --git a/sdk/storage/assets.json b/sdk/storage/assets.json index 8bd090a3b..48de29a0a 100644 --- a/sdk/storage/assets.json +++ b/sdk/storage/assets.json @@ -2,5 +2,5 @@ "AssetsRepo": "Azure/azure-sdk-assets", "AssetsRepoPrefixPath": "cpp", "TagPrefix": "cpp/storage", - "Tag": "cpp/storage_74987cb191" + "Tag": "cpp/storage_bc6afdd1c4" } diff --git a/sdk/storage/azure-storage-files-datalake/test/ut/datalake_directory_client_test.cpp b/sdk/storage/azure-storage-files-datalake/test/ut/datalake_directory_client_test.cpp index 7ca3a137c..a5a457acc 100644 --- a/sdk/storage/azure-storage-files-datalake/test/ut/datalake_directory_client_test.cpp +++ b/sdk/storage/azure-storage-files-datalake/test/ut/datalake_directory_client_test.cpp @@ -37,6 +37,32 @@ namespace Azure { namespace Storage { namespace Test { } } // namespace + TEST_F(DataLakeDirectoryClientTest, Constructors) + { + auto clientOptions = InitStorageClientOptions(); + { + auto directoryClient = Files::DataLake::DataLakeDirectoryClient::CreateFromConnectionString( + AdlsGen2ConnectionString(), m_fileSystemName, m_directoryName, clientOptions); + EXPECT_NO_THROW(directoryClient.GetProperties()); + } + { + auto credential = _internal::ParseConnectionString(AdlsGen2ConnectionString()).KeyCredential; + Files::DataLake::DataLakeDirectoryClient directoryClient( + Files::DataLake::_detail::GetDfsUrlFromUrl(m_directoryClient->GetUrl()), + credential, + clientOptions); + EXPECT_NO_THROW(directoryClient.GetProperties()); + } + { + auto directoryClient = Files::DataLake::DataLakeDirectoryClient( + Files::DataLake::_detail::GetDfsUrlFromUrl(m_directoryClient->GetUrl()), + std::make_shared( + AadTenantId(), AadClientId(), AadClientSecret(), GetTokenCredentialOptions()), + clientOptions); + EXPECT_NO_THROW(directoryClient.GetProperties()); + } + } + TEST_F(DataLakeDirectoryClientTest, CreateDeleteDirectory) { const std::string baseName = RandomString(); @@ -842,4 +868,20 @@ namespace Azure { namespace Storage { namespace Test { } } + TEST_F(DataLakeDirectoryClientTest, ListPathsExpiresOn) + { + const std::string fileName = RandomString(); + auto fileClient = m_directoryClient->GetFileClient(fileName); + fileClient.Create(); + Files::DataLake::ScheduleFileDeletionOptions options; + options.ExpiresOn = Azure::DateTime::Parse( + "Wed, 29 Sep 2100 09:53:03 GMT", Azure::DateTime::DateFormat::Rfc1123); + EXPECT_NO_THROW(fileClient.ScheduleDeletion( + Files::DataLake::ScheduleFileExpiryOriginType::Absolute, options)); + + auto pagedResult = m_directoryClient->ListPaths(true); + EXPECT_EQ(1L, pagedResult.Paths.size()); + ASSERT_TRUE(pagedResult.Paths[0].ExpiresOn.HasValue()); + EXPECT_EQ(options.ExpiresOn.Value(), pagedResult.Paths[0].ExpiresOn.Value()); + } }}} // namespace Azure::Storage::Test diff --git a/sdk/storage/azure-storage-files-datalake/test/ut/datalake_file_client_test.cpp b/sdk/storage/azure-storage-files-datalake/test/ut/datalake_file_client_test.cpp index 3809c2adb..484d01ce6 100644 --- a/sdk/storage/azure-storage-files-datalake/test/ut/datalake_file_client_test.cpp +++ b/sdk/storage/azure-storage-files-datalake/test/ut/datalake_file_client_test.cpp @@ -39,6 +39,32 @@ namespace Azure { namespace Storage { namespace Test { m_fileClient->CreateIfNotExists(); } + TEST_F(DataLakeFileClientTest, Constructors) + { + auto clientOptions = InitStorageClientOptions(); + { + auto fileClient = Files::DataLake::DataLakeFileClient::CreateFromConnectionString( + AdlsGen2ConnectionString(), m_fileSystemName, m_fileName, clientOptions); + EXPECT_NO_THROW(fileClient.GetProperties()); + } + { + auto credential = _internal::ParseConnectionString(AdlsGen2ConnectionString()).KeyCredential; + Files::DataLake::DataLakeFileClient fileClient( + Files::DataLake::_detail::GetDfsUrlFromUrl(m_fileClient->GetUrl()), + credential, + clientOptions); + EXPECT_NO_THROW(fileClient.GetProperties()); + } + { + auto fileClient = Files::DataLake::DataLakeFileClient( + Files::DataLake::_detail::GetDfsUrlFromUrl(m_fileClient->GetUrl()), + std::make_shared( + AadTenantId(), AadClientId(), AadClientSecret(), GetTokenCredentialOptions()), + clientOptions); + EXPECT_NO_THROW(fileClient.GetProperties()); + } + } + TEST_F(DataLakeFileClientTest, BlobUndelete) { auto containerName = m_fileSystemName; @@ -305,6 +331,55 @@ namespace Azure { namespace Storage { namespace Test { } } + TEST_F(DataLakeFileClientTest, AppendFileWithHash) + { + const int32_t bufferSize = 1; + auto buffer = RandomBuffer(bufferSize); + auto bufferStream = std::make_unique( + Azure::Core::IO::MemoryBodyStream(buffer)); + const std::vector contentMd5 + = Azure::Core::Cryptography::Md5Hash().Final(buffer.data(), buffer.size()); + const std::vector contentCrc64 + = Azure::Storage::Crc64Hash().Final(buffer.data(), buffer.size()); + + // MD5 + { + auto client = m_fileSystemClient->GetFileClient(RandomString()); + client.Create(); + auto properties1 = client.GetProperties(); + Files::DataLake::AppendFileOptions options; + options.TransactionalContentHash = ContentHash(); + options.TransactionalContentHash.Value().Algorithm = HashAlgorithm::Md5; + options.TransactionalContentHash.Value().Value = Azure::Core::Convert::Base64Decode(DummyMd5); + bufferStream->Rewind(); + EXPECT_THROW(client.Append(*bufferStream, 0, options), StorageException); + options.TransactionalContentHash.Value().Value = contentMd5; + bufferStream->Rewind(); + EXPECT_NO_THROW(client.Append(*bufferStream, 0, options)); + + Files::DataLake::FlushFileOptions flushOptions; + flushOptions.ContentHash = ContentHash(); + flushOptions.ContentHash.Value().Algorithm = HashAlgorithm::Md5; + flushOptions.ContentHash.Value().Value = contentMd5; + EXPECT_NO_THROW(client.Flush(buffer.size(), flushOptions)); + } + + // CRC64 + { + auto client = m_fileSystemClient->GetFileClient(RandomString()); + client.Create(); + auto properties1 = client.GetProperties(); + Files::DataLake::AppendFileOptions options; + options.Flush = true; + options.TransactionalContentHash = ContentHash(); + options.TransactionalContentHash.Value().Algorithm = HashAlgorithm::Crc64; + options.TransactionalContentHash.Value().Value + = Azure::Core::Convert::Base64Decode(DummyCrc64); + bufferStream->Rewind(); + EXPECT_THROW(client.Append(*bufferStream, 0, options), StorageException); + } + } + TEST_F(DataLakeFileClientTest, AppendFileWithLease) { const int32_t bufferSize = 1; diff --git a/sdk/storage/azure-storage-files-datalake/test/ut/datalake_file_system_client_test.cpp b/sdk/storage/azure-storage-files-datalake/test/ut/datalake_file_system_client_test.cpp index 1067faa0e..286f8865e 100644 --- a/sdk/storage/azure-storage-files-datalake/test/ut/datalake_file_system_client_test.cpp +++ b/sdk/storage/azure-storage-files-datalake/test/ut/datalake_file_system_client_test.cpp @@ -240,6 +240,23 @@ namespace Azure { namespace Storage { namespace Test { } } + TEST_F(DataLakeFileSystemClientTest, ListPathsExpiresOn) + { + const std::string fileName = RandomString(); + auto fileClient = m_fileSystemClient->GetFileClient(fileName); + fileClient.Create(); + Files::DataLake::ScheduleFileDeletionOptions options; + options.ExpiresOn = Azure::DateTime::Parse( + "Wed, 29 Sep 2100 09:53:03 GMT", Azure::DateTime::DateFormat::Rfc1123); + EXPECT_NO_THROW(fileClient.ScheduleDeletion( + Files::DataLake::ScheduleFileExpiryOriginType::Absolute, options)); + + auto pagedResult = m_fileSystemClient->ListPaths(true); + EXPECT_EQ(1L, pagedResult.Paths.size()); + ASSERT_TRUE(pagedResult.Paths[0].ExpiresOn.HasValue()); + EXPECT_EQ(options.ExpiresOn.Value(), pagedResult.Paths[0].ExpiresOn.Value()); + } + TEST_F(DataLakeFileSystemClientTest, UnencodedPathDirectoryFileNameWorks) { const std::string non_ascii_word = "\xE6\xB5\x8B\xE8\xAF\x95"; @@ -807,6 +824,27 @@ namespace Azure { namespace Storage { namespace Test { } } + TEST_F(DataLakeFileSystemClientTest, ListDeletedPathsEncoded) + { + const std::string prefix = "prefix\xEF\xBF\xBF"; + const std::string specialFileName = prefix + "file"; + const std::string specialDirectoryName = prefix + "directory"; + auto fileClient = m_fileSystemClient->GetFileClient(specialFileName); + auto directoryClient = m_fileSystemClient->GetDirectoryClient(specialDirectoryName); + fileClient.Create(); + fileClient.Delete(); + directoryClient.Create(); + directoryClient.DeleteEmpty(); + auto fileUrl = fileClient.GetUrl(); + auto directoryUrl = directoryClient.GetUrl(); + Files::DataLake::ListDeletedPathsOptions options; + options.Prefix = prefix; + auto response = m_fileSystemClient->ListDeletedPaths(options); + EXPECT_EQ(response.DeletedPaths.size(), 2L); + EXPECT_EQ(response.DeletedPaths[0].Name, specialDirectoryName); + EXPECT_EQ(response.DeletedPaths[1].Name, specialFileName); + } + TEST_F(DataLakeFileSystemClientTest, Undelete) { const std::string directoryName = RandomString() + "_dir"; diff --git a/sdk/storage/azure-storage-files-datalake/test/ut/datalake_path_client_test.cpp b/sdk/storage/azure-storage-files-datalake/test/ut/datalake_path_client_test.cpp index ce38084f9..696a658bc 100644 --- a/sdk/storage/azure-storage-files-datalake/test/ut/datalake_path_client_test.cpp +++ b/sdk/storage/azure-storage-files-datalake/test/ut/datalake_path_client_test.cpp @@ -53,6 +53,19 @@ namespace Azure { namespace Storage { namespace Test { return result; } + TEST_F(DataLakePathClientTest, Constructors) + { + auto clientOptions = InitStorageClientOptions(); + { + auto pathClient = Files::DataLake::DataLakePathClient( + Files::DataLake::_detail::GetDfsUrlFromUrl(m_pathClient->GetUrl()), + std::make_shared( + AadTenantId(), AadClientId(), AadClientSecret(), GetTokenCredentialOptions()), + clientOptions); + EXPECT_NO_THROW(pathClient.GetProperties()); + } + } + TEST_F(DataLakePathClientTest, CreateWithOptions) { // owner&group @@ -371,6 +384,36 @@ namespace Azure { namespace Storage { namespace Test { options2.AccessConditions.IfMatch = response.Value.ETag; EXPECT_NO_THROW(m_pathClient->SetAccessControlList(acls, options2)); } + + { + // Set/Get Acls works with scope + std::vector acls = GetAclsForTesting(); + acls[0].Scope = "default"; + auto directoryClient = m_fileSystemClient->GetDirectoryClient(RandomString()); + directoryClient.Create(); + EXPECT_NO_THROW(directoryClient.SetAccessControlList(acls)); + EXPECT_NO_THROW(directoryClient.GetAccessControlList()); + } + } + + TEST_F(DataLakePathClientTest, PathAccessControlsRecursive) + { + // Set Acls Recursive + auto directoryClient = m_fileSystemClient->GetDirectoryClient(RandomString()); + directoryClient.Create(); + auto fileClient = directoryClient.GetFileClient(RandomString()); + fileClient.Create(); + auto acls = directoryClient.GetAccessControlList().Value.Acls; + Files::DataLake::Models::Acl acl; + acl.Permissions = "rwx"; + acl.Id = "72a3f86f-271f-439e-b031-25678907d381"; + acl.Type = "user"; + acls.emplace_back(acl); + Files::DataLake::SetPathAccessControlListRecursiveOptions options; + EXPECT_NO_THROW(directoryClient.SetAccessControlListRecursive(acls)); + EXPECT_NO_THROW(directoryClient.UpdateAccessControlListRecursive(acls)); + acl.Permissions = ""; + EXPECT_NO_THROW(directoryClient.RemoveAccessControlListRecursive({acl})); } TEST_F(DataLakePathClientTest, PathSetPermissions)