diff --git a/eng/pipelines/templates/jobs/archetype-sdk-tests.yml b/eng/pipelines/templates/jobs/archetype-sdk-tests.yml index 1cb5993a81..6f845729ae 100644 --- a/eng/pipelines/templates/jobs/archetype-sdk-tests.yml +++ b/eng/pipelines/templates/jobs/archetype-sdk-tests.yml @@ -149,6 +149,8 @@ jobs: CmakeArgs: "" AZURE_TEST_MODE: "LIVE" AZURE_LOG_LEVEL: "verbose" + # Surface the ServiceDirectory parameter as an environment variable so tests can take advantage of it. + AZURE_SERVICE_DIRECTORY: ${{ parameters.ServiceDirectory }} steps: - checkout: self @@ -218,6 +220,7 @@ jobs: # This enables to run tests and samples at the same time as different matrix configuration. # Then unit-tests runs, samples should not run. condition: and(succeeded(), ne(variables['RunSamples'], '1')) + - task: PublishTestResults@2 inputs: diff --git a/sdk/attestation/azure-security-attestation/README.md b/sdk/attestation/azure-security-attestation/README.md index b211eb9a8a..87f3229181 100644 --- a/sdk/attestation/azure-security-attestation/README.md +++ b/sdk/attestation/azure-security-attestation/README.md @@ -207,16 +207,38 @@ clients to add, remove or enumerate the policy management certificates. The `AttestationClientBuilder` class is used to create instances of the attestation client: ```cpp readme-sample-create-synchronous-client + std::string endpoint = std::getenv("ATTESTATION_AAD_URL"); + AttestationClientOptions options; + return std::make_unique(m_endpoint, options); ``` +If the attestation APIs require authentication, use the following: + +```cpp readme-sample-create-synchronous-client +std::string endpoint = std::getenv("ATTESTATION_AAD_URL"); +AttestationClientOptions options; + std::shared_ptr credential + = std::make_shared( + GetEnv("AZURE_TENANT_ID"), GetEnv("AZURE_CLIENT_ID"), GetEnv("AZURE_CLIENT_SECRET")); +return std::make_unique(m_endpoint, credential, options); +``` + +The same pattern is used to create an `Azure::Security::Attestation::AttestationAdministrationClient`. + #### Retrieve Token Certificates -Use `listAttestationSigners` to retrieve the set of certificates, which can be used to validate the token returned from the attestation service. +Use `GetAttestationSigningCertificates` to retrieve the set of certificates, which can be used to validate the token returned from the attestation service. Normally, this information is not required as the attestation SDK will perform the validation as a part of the interaction with the attestation service, however the APIs are provided for completeness and to facilitate customer's independently validating attestation results. ```cpp readme-sample-getSigningCertificates +auto attestationSigners = attestationClient->GetAttestationSigningCertificates(); +// Enumerate the signers. +for (const auto& signer : attestationSigners.Value.Signers) +{ +} + ``` #### Attest an SGX Enclave @@ -230,22 +252,22 @@ Use the `AttestSgxEnclave` method to attest an SGX enclave. All administrative clients are authenticated. -```cpp readme-sample-create-admin-client -AttestationAdministrationClientBuilder attestationBuilder = new AttestationAdministrationClientBuilder(); -// Note that the "policy" calls require authentication. -AttestationAdministrationClient client = attestationBuilder - .endpoint(endpoint) - .credential(new DefaultAzureCredentialBuilder().build()) - .buildClient(); +```cpp readme-sample-create-synchronous-client +std::string endpoint = std::getenv("ATTESTATION_AAD_URL"); +AttestationClientOptions options; + std::shared_ptr credential + = std::make_shared( + GetEnv("AZURE_TENANT_ID"), GetEnv("AZURE_CLIENT_ID"), GetEnv("AZURE_CLIENT_SECRET")); +auto adminClient = std::make_unique(m_endpoint, credential, options); ``` #### Retrieve current attestation policy for OpenEnclave Use the `GetAttestationPolicy` API to retrieve the current attestation policy for a given TEE. -```java readme-sample-getCurrentPolicy -String currentPolicy = client.getAttestationPolicy(AttestationType.OPEN_ENCLAVE); -System.out.printf("Current policy for OpenEnclave is: %s\n", currentPolicy); +```cpp readme-sample-getCurrentPolicy +auto currentPolicy = adminClient->GetAttestationPolicy(AttestationType.OPEN_ENCLAVE); +std::cout << "Current policy for OpenEnclave is " << currentPolicy.Value.Body << std::endl; ``` #### Set unsigned attestation policy (AAD clients only) @@ -397,3 +419,4 @@ Azure SDK for C++ is licensed under the [MIT](https://github.com/Azure/azure-sdk [cloud_shell_bash]: https://shell.azure.com/bash ![Impressions](https://azure-sdk-impressions.azurewebsites.net/api/impressions/azure-sdk-for-cpp%2Fsdk%2Fattestation%2Fazure-security-attestation%2FREADME.png) + diff --git a/sdk/attestation/azure-security-attestation/src/private/attestation_client_private.hpp b/sdk/attestation/azure-security-attestation/src/private/attestation_client_private.hpp index b3ae8c5161..b5a535ba22 100644 --- a/sdk/attestation/azure-security-attestation/src/private/attestation_client_private.hpp +++ b/sdk/attestation/azure-security-attestation/src/private/attestation_client_private.hpp @@ -425,6 +425,9 @@ namespace Azure { namespace Security { namespace Attestation { namespace _detail ValidateTokenIssuer(validationOptions); } - operator Models::AttestationToken&&() { return std::move(m_token); } + /** + * @brief Convert the internal attestation token to a public AttestationToken object. + */ + operator Models::AttestationToken&() { return m_token; } }; }}}} // namespace Azure::Security::Attestation::_detail diff --git a/sdk/attestation/azure-security-attestation/src/private/crypto/openssl/opensslcert.hpp b/sdk/attestation/azure-security-attestation/src/private/crypto/openssl/opensslcert.hpp index 5b678d1d94..5e41033b26 100644 --- a/sdk/attestation/azure-security-attestation/src/private/crypto/openssl/opensslcert.hpp +++ b/sdk/attestation/azure-security-attestation/src/private/crypto/openssl/opensslcert.hpp @@ -140,7 +140,7 @@ namespace Azure { namespace Security { namespace Attestation { namespace _detail { throw OpenSSLException("i2d_X509"); } - if (EVP_DigestUpdate(hash.get(), buf, thumbprintBuffer.size()) != 1) + if (EVP_DigestUpdate(hash.get(), thumbprintBuffer.data(), thumbprintBuffer.size()) != 1) { throw OpenSSLException("EVP_DigestUpdate"); } diff --git a/sdk/attestation/azure-security-attestation/test/ut/administration_test.cpp b/sdk/attestation/azure-security-attestation/test/ut/administration_test.cpp index aebb8883db..4874faea70 100644 --- a/sdk/attestation/azure-security-attestation/test/ut/administration_test.cpp +++ b/sdk/attestation/azure-security-attestation/test/ut/administration_test.cpp @@ -5,6 +5,7 @@ #include "azure/identity/client_secret_credential.hpp" #include #include +#include #include #include #include diff --git a/sdk/core/azure-core-test/inc/azure/core/test/test_base.hpp b/sdk/core/azure-core-test/inc/azure/core/test/test_base.hpp index ec916d032f..3889ec3597 100644 --- a/sdk/core/azure-core-test/inc/azure/core/test/test_base.hpp +++ b/sdk/core/azure-core-test/inc/azure/core/test/test_base.hpp @@ -243,13 +243,62 @@ namespace Azure { namespace Core { namespace Test { "Test Log from: [ " + m_testContext.GetTestPlaybackRecordingName() + " ] - " + message); } - // Util for tests getting env vars - std::string GetEnv(const std::string& name) + /** + * @brief Utility function used by tests to retrieve env vars + * + * @param name Environment variable name to retrieve. + * + * @return The value of the environment variable retrieved. + * + * @note If AZURE_TENANT_ID, AZURE_CLIENT_ID, or AZURE_CLIENT_SECRET are not available in the + * environment, the AZURE_SERVICE_DIRECTORY environment variable is used to set those values + * with the values emitted by the New-TestResources.ps1 script. + * + * @note The Azure CI pipeline upper cases all environment variables defined in the pipeline. + * Since some operating systems have case sensitive environment variables, on debug builds, this + * function ensures that the environment variable being retrieved is all upper case. + * + */ + std::string GetEnv(std::string const& name) { - const auto ret = Azure::Core::_internal::Environment::GetVariable(name.c_str()); - +#if !defined(NDEBUG) + // The azure CI pipeline uppercases all EnvVar values from ci.yml files. + // That means that any mixed case strings will not be found when run from the CI + // pipeline. Check to make sure that the developer only passed in an upper case environment + // variable. + { + if (name != Azure::Core::_internal::StringExtensions::ToUpper(name)) + { + throw std::runtime_error("All Azure SDK environment variables must be all upper case."); + } + } +#endif + auto ret = Azure::Core::_internal::Environment::GetVariable(name.c_str()); if (ret.empty()) { + static const char azurePrefix[] = "AZURE_"; + if (!m_testContext.IsPlaybackMode() && name.find(azurePrefix) == 0) + { + std::string serviceDirectory + = Azure::Core::_internal::Environment::GetVariable("AZURE_SERVICE_DIRECTORY"); + if (serviceDirectory.empty()) + { + throw std::runtime_error( + "Could not find a value for " + name + + " and AZURE_SERVICE_DIRECTORY was not defined. Define either " + name + + " or AZURE_SERVICE_DIRECTORY to resolve."); + } + // Upper case the serviceName environment variable because all ci.yml environment + // variables are upper cased. + std::string serviceDirectoryEnvVar + = Azure::Core::_internal::StringExtensions::ToUpper(serviceDirectory); + serviceDirectoryEnvVar += name.substr(sizeof(azurePrefix) - 2); + ret = Azure::Core::_internal::Environment::GetVariable(serviceDirectoryEnvVar.c_str()); + if (!ret.empty()) + { + return ret; + } + } throw std::runtime_error("Missing required environment variable: " + name); } @@ -261,6 +310,15 @@ namespace Azure { namespace Core { namespace Test { /** * @brief Run before each test. * + * @param baseRecordingPath - the base recording path to be used for this test. Normally this is + * `AZURE_TEST_RECORDING_DIR`. + * + * For example: + * + * \code{.cpp} + * Azure::Core::Test::TestBase::SetUpTestBase(AZURE_TEST_RECORDING_DIR); + * \endcode + * */ void SetUpTestBase(std::string const& baseRecordingPath) { diff --git a/sdk/core/azure-core/inc/azure/core/internal/strings.hpp b/sdk/core/azure-core/inc/azure/core/internal/strings.hpp index d6e68d2e17..0858c230e4 100644 --- a/sdk/core/azure-core/inc/azure/core/internal/strings.hpp +++ b/sdk/core/azure-core/inc/azure/core/internal/strings.hpp @@ -33,8 +33,10 @@ namespace Azure { namespace Core { namespace _internal { static bool LocaleInvariantCaseInsensitiveEqual( const std::string& lhs, const std::string& rhs) noexcept; - static std::string const ToLower(const std::string& src) noexcept; - static unsigned char ToLower(const unsigned char src) noexcept; + static std::string const ToLower(std::string const& src) noexcept; + static unsigned char ToLower(unsigned char const src) noexcept; + static std::string const ToUpper(std::string const& src) noexcept; + static unsigned char ToUpper(unsigned char const src) noexcept; }; }}} // namespace Azure::Core::_internal diff --git a/sdk/core/azure-core/src/http/winhttp/win_http_transport.cpp b/sdk/core/azure-core/src/http/winhttp/win_http_transport.cpp index 50fa628815..8c26b0ca71 100644 --- a/sdk/core/azure-core/src/http/winhttp/win_http_transport.cpp +++ b/sdk/core/azure-core/src/http/winhttp/win_http_transport.cpp @@ -303,6 +303,9 @@ void WinHttpTransport::CreateRequestHandle(std::unique_ptr<_detail::HandleManage { const std::string& path = handleManager->m_request.GetUrl().GetRelativeUrl(); HttpMethod requestMethod = handleManager->m_request.GetMethod(); + bool const requestSecureHttp( + !Azure::Core::_internal::StringExtensions::LocaleInvariantCaseInsensitiveEqual( + handleManager->m_request.GetUrl().GetScheme(), HttpScheme)); // Create an HTTP request handle. handleManager->m_requestHandle = WinHttpOpenRequest( @@ -314,10 +317,7 @@ void WinHttpTransport::CreateRequestHandle(std::unique_ptr<_detail::HandleManage NULL, // Use HTTP/1.1 WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, // No media types are accepted by the client - Azure::Core::_internal::StringExtensions::LocaleInvariantCaseInsensitiveEqual( - handleManager->m_request.GetUrl().GetScheme(), HttpScheme) - ? 0 - : WINHTTP_FLAG_SECURE); // Uses secure transaction semantics (SSL/TLS) + requestSecureHttp ? WINHTTP_FLAG_SECURE : 0); // Uses secure transaction semantics (SSL/TLS) if (!handleManager->m_requestHandle) { @@ -330,6 +330,23 @@ void WinHttpTransport::CreateRequestHandle(std::unique_ptr<_detail::HandleManage // ERROR_NOT_ENOUGH_MEMORY GetErrorAndThrow("Error while getting a request handle."); } + + if (requestSecureHttp) + { + // If the service requests TLS client certificates, we want to let the WinHTTP APIs know that + // it's ok to initiate the request without a client certificate. + // + // Note: If/When TLS client certificate support is added to the pipeline, this line may need to + // be revisited. + if (!WinHttpSetOption( + handleManager->m_requestHandle, + WINHTTP_OPTION_CLIENT_CERT_CONTEXT, + WINHTTP_NO_CLIENT_CERT_CONTEXT, + 0)) + { + GetErrorAndThrow("Error while setting client cert context to ignore.."); + } + } } // For PUT/POST requests, send additional data using WinHttpWriteData. diff --git a/sdk/core/azure-core/src/strings.cpp b/sdk/core/azure-core/src/strings.cpp index 4047bc5a95..702ebd1b68 100644 --- a/sdk/core/azure-core/src/strings.cpp +++ b/sdk/core/azure-core/src/strings.cpp @@ -65,11 +65,29 @@ const unsigned char LocaleInvariantLowercaseTable[256] = { 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, }; +const unsigned char LocaleInvariantUppercaseTable[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, + 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, + 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, + 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, + 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, + 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, +}; } // unnamed namespace namespace Azure { namespace Core { namespace _internal { - unsigned char StringExtensions::ToLower(const unsigned char symbol) noexcept + unsigned char StringExtensions::ToLower(unsigned char const symbol) noexcept { return LocaleInvariantLowercaseTable[symbol]; } @@ -77,10 +95,23 @@ namespace Azure { namespace Core { namespace _internal { std::string const StringExtensions::ToLower(const std::string& src) noexcept { auto result = std::string(src); - for (auto i = result.begin(); i < result.end(); i++) - { - *i = ToLower(static_cast(*i)); - } + std::transform(result.begin(), result.end(), result.begin(), [](char const ch) { + return StringExtensions::ToLower(ch); + }); + return result; + } + + unsigned char StringExtensions::ToUpper(unsigned char const symbol) noexcept + { + return LocaleInvariantUppercaseTable[symbol]; + } + + std::string const StringExtensions::ToUpper(const std::string& src) noexcept + { + auto result = std::string(src); + std::transform(result.begin(), result.end(), result.begin(), [](char const ch) { + return StringExtensions::ToUpper(ch); + }); return result; } diff --git a/sdk/core/azure-core/test/ut/string_test.cpp b/sdk/core/azure-core/test/ut/string_test.cpp index dc0c9c4a48..91d277ff74 100644 --- a/sdk/core/azure-core/test/ut/string_test.cpp +++ b/sdk/core/azure-core/test/ut/string_test.cpp @@ -20,6 +20,24 @@ TEST(String, invariantCompare) EXPECT_FALSE(StringExtensions::LocaleInvariantCaseInsensitiveEqual("ABC", "abcd")); } +TEST(String, toLowerC) +{ + using Azure::Core::_internal::StringExtensions; + for (unsigned char ch = 0; ch < 255; ch += 1) + { + EXPECT_TRUE(StringExtensions::ToLower(ch) == std::tolower(ch)); + } +} + +TEST(String, toUpperC) +{ + using Azure::Core::_internal::StringExtensions; + for (unsigned char ch = 0; ch < 255; ch += 1) + { + EXPECT_TRUE(StringExtensions::ToUpper(ch) == std::toupper(ch)); + } +} + TEST(String, toLower) { using Azure::Core::_internal::StringExtensions; @@ -29,9 +47,33 @@ TEST(String, toLower) EXPECT_TRUE(StringExtensions::ToLower("AA") == "aa"); EXPECT_TRUE(StringExtensions::ToLower("aA") == "aa"); EXPECT_TRUE(StringExtensions::ToLower("ABC") == "abc"); + EXPECT_TRUE( + StringExtensions::ToLower("abcdefghijklmnopqrstuvwxyz") == "abcdefghijklmnopqrstuvwxyz"); + EXPECT_TRUE( + StringExtensions::ToLower("ABCDEFGHIJKLMNOPQRSTUVWXYZ") == "abcdefghijklmnopqrstuvwxyz"); EXPECT_TRUE(StringExtensions::ToLower("ABC-1-,!@#$%^&*()_+=ABC") == "abc-1-,!@#$%^&*()_+=abc"); EXPECT_FALSE(StringExtensions::ToLower("") == "a"); EXPECT_FALSE(StringExtensions::ToLower("a") == ""); EXPECT_FALSE(StringExtensions::ToLower("a") == "aA"); EXPECT_FALSE(StringExtensions::ToLower("abc") == "abcd"); } + +TEST(String, toUpper) +{ + using Azure::Core::_internal::StringExtensions; + EXPECT_TRUE(StringExtensions::ToUpper("") == ""); + EXPECT_TRUE(StringExtensions::ToUpper("a") == "A"); + EXPECT_TRUE(StringExtensions::ToUpper("A") == "A"); + EXPECT_TRUE(StringExtensions::ToUpper("AA") == "AA"); + EXPECT_TRUE(StringExtensions::ToUpper("aA") == "AA"); + EXPECT_TRUE( + StringExtensions::ToUpper("ABCDEFGHIJKLMNOPQRSTUVWXYZ") == "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + EXPECT_TRUE(StringExtensions::ToUpper("ABC") == "ABC"); + EXPECT_TRUE( + StringExtensions::ToUpper("ABCDEFGHIJKLMNOPQRSTUVWXYZ") == "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + EXPECT_TRUE(StringExtensions::ToUpper("ABC-1-,!@#$%^&*()_+=ABC") == "ABC-1-,!@#$%^&*()_+=ABC"); + EXPECT_FALSE(StringExtensions::ToUpper("") == "A"); + EXPECT_FALSE(StringExtensions::ToUpper("a") == ""); + EXPECT_FALSE(StringExtensions::ToUpper("a") == "aA"); + EXPECT_FALSE(StringExtensions::ToUpper("abc") == "abcd"); +} diff --git a/sdk/storage/azure-storage-blobs/test/ut/block_blob_client_test.cpp b/sdk/storage/azure-storage-blobs/test/ut/block_blob_client_test.cpp index 3f58a6595e..89d5ccce45 100644 --- a/sdk/storage/azure-storage-blobs/test/ut/block_blob_client_test.cpp +++ b/sdk/storage/azure-storage-blobs/test/ut/block_blob_client_test.cpp @@ -701,7 +701,7 @@ namespace Azure { namespace Storage { namespace Test { TEST_P(DownloadBlockBlob, downloadToBuffer) { - auto const p = GetParam(); + BlobConcurrentDownloadParameter const& p(GetParam()); auto const testName(GetTestName(true)); auto client = GetBlockBlobClient(testName); UploadBlockBlob(8_MB); @@ -773,7 +773,7 @@ namespace Azure { namespace Storage { namespace Test { TEST_P(DownloadBlockBlob, downloadToFile) { - auto const p = GetParam(); + BlobConcurrentDownloadParameter const& p(GetParam()); auto const testName(GetTestName(true)); auto client = GetBlockBlobClient(testName); UploadBlockBlob(8_MB); @@ -1191,7 +1191,7 @@ namespace Azure { namespace Storage { namespace Test { auto const testName(GetTestName()); auto blockBlobClient = GetBlockBlobClient(testName); SetOptions(); - auto const p = GetParam(); + UploadBlockBlob::ParamType const& p(GetParam()); auto const blobSize = p.Size; std::vector blobContent(static_cast(8_MB), 'x'); @@ -1227,7 +1227,7 @@ namespace Azure { namespace Storage { namespace Test { auto const testName(GetTestName()); auto blockBlobClient = GetBlockBlobClient(testName); SetOptions(); - auto const p = GetParam(); + UploadBlockBlob::ParamType const& p(GetParam()); auto const blobSize = p.Size; std::vector blobContent(static_cast(8_MB), 'x'); 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 b79db998af..edf1723852 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 @@ -429,7 +429,7 @@ namespace Azure { namespace Storage { namespace Test { TEST_P(UploadFile, fromBuffer) { - auto const p = GetParam(); + UploadFile::ParamType const& p(GetParam()); std::vector fileContent(static_cast(8_MB), 'x'); auto fileClient = m_fileSystemClient->GetFileClient(GetTestNameLowerCase()); @@ -461,7 +461,7 @@ namespace Azure { namespace Storage { namespace Test { TEST_P(UploadFile, fromFile) { - auto const p = GetParam(); + UploadFile::ParamType const& p(GetParam()); std::vector fileContent(static_cast(8_MB), 'x'); auto fileClient = m_fileSystemClient->GetFileClient(GetTestNameLowerCase()); diff --git a/sdk/storage/azure-storage-files-shares/test/ut/share_file_client_test.cpp b/sdk/storage/azure-storage-files-shares/test/ut/share_file_client_test.cpp index 7f45637c2e..fed1ae16f0 100644 --- a/sdk/storage/azure-storage-files-shares/test/ut/share_file_client_test.cpp +++ b/sdk/storage/azure-storage-files-shares/test/ut/share_file_client_test.cpp @@ -395,7 +395,7 @@ namespace Azure { namespace Storage { namespace Test { TEST_P(UploadShare, fromBuffer) { - auto const p = GetParam(); + UploadShare::ParamType const& p(GetParam()); auto fileClient = m_fileShareDirectoryClient->GetFileClient(m_testName); std::vector fileContent(static_cast(p.FileSize), 'x'); @@ -418,7 +418,7 @@ namespace Azure { namespace Storage { namespace Test { TEST_P(UploadShare, fromFile) { - auto const p = GetParam(); + UploadShare::ParamType const& p(GetParam()); auto fileClient = m_fileShareDirectoryClient->GetFileClient(m_testName); std::vector fileContent = std::vector(static_cast(p.FileSize), 'x');