From a2b2b740801aed7abd28d0d35a5b32000e658b10 Mon Sep 17 00:00:00 2001 From: Anton Kolesnyk <41349689+antkmsft@users.noreply.github.com> Date: Mon, 13 Dec 2021 14:50:30 -0800 Subject: [PATCH] Add a few simple unit tests to boost coverage (#3163) --- sdk/core/azure-core/src/http/curl/curl.cpp | 2 +- .../src/http/curl/curl_connection_private.hpp | 2 +- sdk/core/azure-core/test/ut/CMakeLists.txt | 2 +- .../test/ut/curl_connection_pool_test.cpp | 10 ++ sdk/core/azure-core/test/ut/datetime_test.cpp | 76 +++++++++++++++ ...> environment_log_level_listener_test.cpp} | 17 ++++ .../azure-core/test/ut/exception_test.cpp | 47 +++++++++ .../azure-core/test/ut/log_policy_test.cpp | 44 +++++++-- sdk/core/azure-core/test/ut/pipeline_test.cpp | 68 +++++++++++++ .../azure-core/test/ut/retry_policy_test.cpp | 97 ++++++++++++++++++- sdk/core/azure-core/test/ut/sha_test.cpp | 24 +++++ sdk/core/azure-core/test/ut/url_test.cpp | 18 ++++ sdk/core/ci.yml | 4 +- 13 files changed, 396 insertions(+), 15 deletions(-) rename sdk/core/azure-core/test/ut/{environmentLogLevelListener_test.cpp => environment_log_level_listener_test.cpp} (92%) diff --git a/sdk/core/azure-core/src/http/curl/curl.cpp b/sdk/core/azure-core/src/http/curl/curl.cpp index 06ff40eab..1e27d43c6 100644 --- a/sdk/core/azure-core/src/http/curl/curl.cpp +++ b/sdk/core/azure-core/src/http/curl/curl.cpp @@ -915,7 +915,7 @@ void CurlConnection::Shutdown() #elif defined(AZ_PLATFORM_WINDOWS) ::shutdown(m_curlSocket, SD_BOTH); #endif - m_isShutDown = true; + CurlNetworkConnection::Shutdown(); } // Read from socket and return the number of bytes taken from socket diff --git a/sdk/core/azure-core/src/http/curl/curl_connection_private.hpp b/sdk/core/azure-core/src/http/curl/curl_connection_private.hpp index 5b5c8bd10..496584810 100644 --- a/sdk/core/azure-core/src/http/curl/curl_connection_private.hpp +++ b/sdk/core/azure-core/src/http/curl/curl_connection_private.hpp @@ -57,7 +57,7 @@ namespace Azure { namespace Core { namespace Http { * */ class CurlNetworkConnection { - protected: + private: bool m_isShutDown = false; public: diff --git a/sdk/core/azure-core/test/ut/CMakeLists.txt b/sdk/core/azure-core/test/ut/CMakeLists.txt index a430ff81d..92cbc7320 100644 --- a/sdk/core/azure-core/test/ut/CMakeLists.txt +++ b/sdk/core/azure-core/test/ut/CMakeLists.txt @@ -46,7 +46,7 @@ add_executable ( ${CURL_OPTIONS_TESTS} ${CURL_SESSION_TESTS} datetime_test.cpp - environmentLogLevelListener_test.cpp + environment_log_level_listener_test.cpp etag_test.cpp http_test.cpp http_test.hpp diff --git a/sdk/core/azure-core/test/ut/curl_connection_pool_test.cpp b/sdk/core/azure-core/test/ut/curl_connection_pool_test.cpp index 40c93ad1f..720a35740 100644 --- a/sdk/core/azure-core/test/ut/curl_connection_pool_test.cpp +++ b/sdk/core/azure-core/test/ut/curl_connection_pool_test.cpp @@ -161,6 +161,16 @@ namespace Azure { namespace Core { namespace Test { EXPECT_EQ(values->second.begin()->get()->GetConnectionKey(), expectedConnectionKey); } + { + Azure::Core::Http::CurlSession::ResponseBufferParser responseParser; + EXPECT_EQ(responseParser.ExtractResponse(), nullptr); + + const uint8_t responseBuf[] = "HTTP/1.1 200 OK\r\n\r\n"; + static_cast(responseParser.Parse(responseBuf, sizeof(responseBuf) - 1)); + EXPECT_NE(responseParser.ExtractResponse(), nullptr); + EXPECT_EQ(responseParser.ExtractResponse(), nullptr); + } + // Test re-using same custom config { // Creating a new connection with default options diff --git a/sdk/core/azure-core/test/ut/datetime_test.cpp b/sdk/core/azure-core/test/ut/datetime_test.cpp index a962f52f8..249681992 100644 --- a/sdk/core/azure-core/test/ut/datetime_test.cpp +++ b/sdk/core/azure-core/test/ut/datetime_test.cpp @@ -6,6 +6,7 @@ #include #include +#include #include using namespace Azure; @@ -373,6 +374,18 @@ TEST(DateTime, ParseTimeRfc3339BoundaryCases) "2038-01-19T03:13:07-00:01", "2038-01-19T03:14:07Z"); // INT_MAX after subtacting 1 TestDateTimeRoundtrip("2038-01-19T03:14:07-00:00", "2038-01-19T03:14:07Z"); + + // No ':' in time zone offset + EXPECT_THROW( + DateTime::Parse("2001-01-01T00:00:00+12345", DateTime::DateFormat::Rfc3339), + std::invalid_argument); +} + +TEST(DateTime, ParseUnrecognizedFormat) +{ + EXPECT_THROW( + DateTime::Parse("2001-01-01T00:00:00", static_cast(42)), + std::invalid_argument); } TEST(DateTime, ParseTimeRfc3339UsesEachTimezoneDigit) @@ -819,3 +832,66 @@ TEST(DateTime, ParseRoundUpInvalidDate) static_cast(DateTime::Parse("9999-12-31T23:59:60", DateTime::DateFormat::Rfc3339)), std::invalid_argument); } + +TEST(DateTime, ToSystemClock) +{ + if (DateTime(std::chrono::system_clock::time_point::min()) + > DateTime(DateTime::time_point::min())) + { + EXPECT_THROW( + static_cast(static_cast( + DateTime(DateTime::time_point::min()))), + std::invalid_argument); + } + + if (DateTime(std::chrono::system_clock::time_point::max()) + > DateTime(DateTime::time_point::max())) + { + EXPECT_THROW( + static_cast(static_cast( + DateTime(DateTime::time_point::max()))), + std::invalid_argument); + } + + { + auto const tt = std::chrono::system_clock::to_time_t( + static_cast(DateTime(2021, 7, 8, 15, 34, 56))); + +#ifdef _MSC_VER +#pragma warning(push) +// warning C4996: 'gmtime': This function or variable may be unsafe. Consider using gmtime_s +// instead. +#pragma warning(disable : 4996) +#endif + auto const tm = std::gmtime(&tt); +#ifdef _MSC_VER +#pragma warning(pop) +#endif + + // https://en.cppreference.com/w/cpp/chrono/c/tm + EXPECT_EQ(tm->tm_year, (2021 - 1900)); // std::tm::tm_year is 1900-based. + EXPECT_EQ(tm->tm_mon, 6); // std::tm::tm_mon is 0-based. + EXPECT_EQ(tm->tm_mday, 8); + EXPECT_EQ(tm->tm_hour, 15); + EXPECT_EQ(tm->tm_min, 34); + EXPECT_EQ(tm->tm_sec, 56); + } +} + +TEST(DateTime, OutOfToStringRange) +{ + using namespace std::literals::chrono_literals; + + const DateTime underflow(DateTime(0001) - 1s); + const DateTime overflow(DateTime(9999, 12, 31, 23, 59, 59) + 1s); + + EXPECT_THROW(static_cast(underflow.ToString()), std::invalid_argument); + EXPECT_THROW(static_cast(overflow.ToString()), std::invalid_argument); +} + +TEST(DateTime, LeapYear) +{ + EXPECT_NO_THROW(static_cast(DateTime(2021, 1, 29))); + EXPECT_NO_THROW(static_cast(DateTime(2021, 2, 28))); + EXPECT_THROW(static_cast(DateTime(2021, 2, 29)), std::invalid_argument); +} diff --git a/sdk/core/azure-core/test/ut/environmentLogLevelListener_test.cpp b/sdk/core/azure-core/test/ut/environment_log_level_listener_test.cpp similarity index 92% rename from sdk/core/azure-core/test/ut/environmentLogLevelListener_test.cpp rename to sdk/core/azure-core/test/ut/environment_log_level_listener_test.cpp index 19c42ec7e..fb63af6f1 100644 --- a/sdk/core/azure-core/test/ut/environmentLogLevelListener_test.cpp +++ b/sdk/core/azure-core/test/ut/environment_log_level_listener_test.cpp @@ -200,3 +200,20 @@ TEST_F(EnvironmentLogLevelListenerTest, GetLogListenerInformational) EXPECT_NE(buffer.str().find("INFO : message"), std::string::npos); std::cerr.rdbuf(old); } + +TEST_F(EnvironmentLogLevelListenerTest, GetLogListenerUnknown) +{ + EnvironmentLogLevelListener::SetInitialized(false); + SetLogLevel("verbose"); + + std::stringstream buffer; + std::streambuf* old = std::cerr.rdbuf(buffer.rdbuf()); + + std::string text = buffer.str(); // text will now contain "Bla\n" + auto listener = EnvironmentLogLevelListener::GetLogListener(); + + listener(static_cast(42), "message"); + EXPECT_NE(listener, nullptr); + EXPECT_NE(buffer.str().find("????? : message"), std::string::npos); + std::cerr.rdbuf(old); +} diff --git a/sdk/core/azure-core/test/ut/exception_test.cpp b/sdk/core/azure-core/test/ut/exception_test.cpp index bcd3c7487..d520baf22 100644 --- a/sdk/core/azure-core/test/ut/exception_test.cpp +++ b/sdk/core/azure-core/test/ut/exception_test.cpp @@ -32,6 +32,8 @@ TEST(RequestFailedException, JSONError) EXPECT_EQ(exception.ErrorCode, "503"); EXPECT_EQ(exception.RequestId, "1"); EXPECT_EQ(exception.ClientRequestId, "2"); + EXPECT_EQ(exception.ReasonPhrase, "retry please :"); + EXPECT_EQ(exception.what(), std::string("Received an HTTP unsuccessful status code.")); } TEST(RequestFailedException, JSONErrorNoError) @@ -55,4 +57,49 @@ TEST(RequestFailedException, JSONErrorNoError) EXPECT_EQ(exception.ErrorCode, ""); EXPECT_EQ(exception.RequestId, "1"); EXPECT_EQ(exception.ClientRequestId, "2"); + EXPECT_EQ(exception.ReasonPhrase, "retry please :"); + EXPECT_EQ(exception.what(), std::string("Received an HTTP unsuccessful status code.")); +} + +TEST(RequestFailedException, EmptyValues) +{ + auto response = std::make_unique( + 1, 1, Azure::Core::Http::HttpStatusCode::None, std::string()); + + auto exception = Azure::Core::RequestFailedException(response); + + EXPECT_EQ(exception.StatusCode, Azure::Core::Http::HttpStatusCode::None); + EXPECT_EQ(exception.Message, std::string()); + EXPECT_EQ(exception.ErrorCode, std::string()); + EXPECT_EQ(exception.RequestId, std::string()); + EXPECT_EQ(exception.ClientRequestId, std::string()); + EXPECT_EQ(exception.ReasonPhrase, std::string()); + EXPECT_EQ(exception.what(), std::string("Received an HTTP unsuccessful status code.")); +} + +TEST(RequestFailedException, Message) +{ + auto response = std::make_unique( + 1, 1, Azure::Core::Http::HttpStatusCode::ServiceUnavailable, "retry please :"); + static constexpr uint8_t const responseBody[] + = "{\"error\":{ \"code\":\"503\", \"message\":\"JT\"}}"; + static constexpr uint8_t const responseBodyStream[] + = "{\"error\":{ \"code\":\"503\", \"message\":\"JT\"}}"; + + response->SetHeader(HttpShared::ContentType, "application/json"); + response->SetHeader(HttpShared::MsRequestId, "1"); + response->SetHeader(HttpShared::MsClientRequestId, "2"); + response->SetBody(std::vector(responseBody, responseBody + sizeof(responseBody))); + response->SetBodyStream(std::make_unique( + responseBodyStream, sizeof(responseBodyStream) - 1)); + + auto exception = Azure::Core::RequestFailedException("Msg", std::move(response)); + + EXPECT_EQ(exception.StatusCode, Azure::Core::Http::HttpStatusCode::ServiceUnavailable); + EXPECT_EQ(exception.Message, "Msg"); + EXPECT_EQ(exception.ErrorCode, ""); + EXPECT_EQ(exception.RequestId, "1"); + EXPECT_EQ(exception.ClientRequestId, "2"); + EXPECT_EQ(exception.ReasonPhrase, "retry please :"); + EXPECT_EQ(exception.what(), std::string("Msg")); } diff --git a/sdk/core/azure-core/test/ut/log_policy_test.cpp b/sdk/core/azure-core/test/ut/log_policy_test.cpp index c4e905f71..32ddb6f43 100644 --- a/sdk/core/azure-core/test/ut/log_policy_test.cpp +++ b/sdk/core/azure-core/test/ut/log_policy_test.cpp @@ -13,7 +13,7 @@ using Azure::Core::Http::Policies::LogOptions; // cspell:ignore qparam namespace { -void SendRequest(LogOptions const& logOptions) +void SendRequest(LogOptions const& logOptions, std::string const& portAndPath = "") { using namespace Azure::Core; using namespace Azure::Core::IO; @@ -51,13 +51,12 @@ void SendRequest(LogOptions const& logOptions) Request request( HttpMethod::Get, - Url("https://" - "www.microsoft.com" - "?qparam1=qVal1" - "&Qparam2=Qval2" - "&qParam3=qval3" - "&qparam%204=qval%204" - "&qparam%25204=QVAL%25204"), + Url(std::string("https://www.microsoft.com") + portAndPath + + "?qparam1=qVal1" + "&Qparam2=Qval2" + "&qParam3=qval3" + "&qparam%204=qval%204" + "&qparam%25204=QVAL%25204"), bodyStream.get()); request.SetHeader("hEaDeR1", "HvAlUe1"); @@ -154,6 +153,35 @@ TEST(LogPolicy, Default) EXPECT_TRUE(EndsWith(entry2.Message, "ms) : 200 OKAY")); } +TEST(LogPolicy, PortAndPath) +{ + TestLogger const Log; + SendRequest(LogOptions(), ":8080/path"); + + EXPECT_EQ(Log.Entries.size(), 2); + + auto const entry1 = Log.Entries.at(0); + auto const entry2 = Log.Entries.at(1); + + EXPECT_EQ(entry1.Level, Logger::Level::Informational); + EXPECT_EQ(entry2.Level, Logger::Level::Informational); + + EXPECT_EQ( + entry1.Message, + "HTTP Request : GET https://www.microsoft.com:8080/path" + "?Qparam2=REDACTED" + "&qParam3=REDACTED" + "&qparam%204=REDACTED" + "&qparam%25204=REDACTED" + "&qparam1=REDACTED" + "\nheader1 : REDACTED" + "\nheader2 : REDACTED" + "\nx-ms-request-id : 6c536700-4c36-4e22-9161-76e7b3bf8269"); + + EXPECT_TRUE(StartsWith(entry2.Message, "HTTP Response (")); + EXPECT_TRUE(EndsWith(entry2.Message, "ms) : 200 OKAY")); +} + TEST(LogPolicy, Headers) { TestLogger const Log; diff --git a/sdk/core/azure-core/test/ut/pipeline_test.cpp b/sdk/core/azure-core/test/ut/pipeline_test.cpp index 9752c6f87..c311ab8b8 100644 --- a/sdk/core/azure-core/test/ut/pipeline_test.cpp +++ b/sdk/core/azure-core/test/ut/pipeline_test.cpp @@ -51,3 +51,71 @@ TEST(Pipeline, refrefEmptyPipeline) std::vector>(0)), std::invalid_argument); } + +TEST(Pipeline, AdditionalPolicies) +{ + class TestPolicy : public Azure::Core::Http::Policies::HttpPolicy { + int* m_cloneCount; + + public: + TestPolicy(int* cloneCount) : m_cloneCount(cloneCount) {} + + std::unique_ptr Clone() const override + { + ++(*m_cloneCount); + return std::make_unique(*this); + } + + std::unique_ptr Send( + Azure::Core::Http::Request& request, + Azure::Core::Http::Policies::NextHttpPolicy nextPolicy, + Azure::Core::Context const& context) const override + { + return nextPolicy.Send(request, context); + } + }; + + int perCallPolicyCloneCount = 0; + int perCallClientPolicyCloneCount = 0; + int perRetryPolicyCloneCount = 0; + int perRetryClientPolicyCloneCount = 0; + + auto options = Azure::Core::_internal::ClientOptions(); + + using PolicyVector = std::vector>; + PolicyVector perCallPolicies; + PolicyVector perRetryPolicies; + + { + struct InitHelper + { + PolicyVector* Policies; + int* Counter; + }; + + std::vector const initializations = { + {&perCallPolicies, &perCallPolicyCloneCount}, + {&options.PerOperationPolicies, &perCallClientPolicyCloneCount}, + {&perRetryPolicies, &perRetryPolicyCloneCount}, + {&options.PerRetryPolicies, &perRetryClientPolicyCloneCount}, + }; + + const int size = static_cast(initializations.size()); + for (int i = 0; i < size; ++i) + { + for (int j = 0; j < i + 2; ++j) + { + initializations[i].Policies->emplace_back( + std::make_unique(initializations[i].Counter)); + } + } + } + + EXPECT_NO_THROW(static_cast(Azure::Core::Http::_internal::HttpPipeline( + options, "Test", "1.0.0", std::move(perRetryPolicies), std::move(perCallPolicies)))); + + EXPECT_EQ(perCallPolicyCloneCount, 2); + EXPECT_EQ(perCallClientPolicyCloneCount, 3); + EXPECT_EQ(perRetryPolicyCloneCount, 4); + EXPECT_EQ(perRetryClientPolicyCloneCount, 5); +} diff --git a/sdk/core/azure-core/test/ut/retry_policy_test.cpp b/sdk/core/azure-core/test/ut/retry_policy_test.cpp index 5bf51ba71..d456bf8cf 100644 --- a/sdk/core/azure-core/test/ut/retry_policy_test.cpp +++ b/sdk/core/azure-core/test/ut/retry_policy_test.cpp @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // SPDX-License-Identifier: MIT +#include "azure/core/diagnostics/logger.hpp" #include "azure/core/http/policies/policy.hpp" #include "azure/core/internal/http/pipeline.hpp" @@ -54,8 +55,24 @@ public: int32_t, std::chrono::milliseconds&, double)> shouldRetryOnResponse) - : RetryPolicy(retryOptions), m_shouldRetryOnTransportFailure(shouldRetryOnTransportFailure), - m_shouldRetryOnResponse(shouldRetryOnResponse) + : RetryPolicy(retryOptions), + m_shouldRetryOnTransportFailure( + shouldRetryOnTransportFailure != nullptr + ? shouldRetryOnTransportFailure + : [&](auto options, auto attempt, auto retryAfter, auto jitter) { + retryAfter = std::chrono::milliseconds(0); + auto ignore = decltype(retryAfter)(); + return RetryPolicy::ShouldRetryOnTransportFailure(options, attempt, ignore, jitter); + }), + m_shouldRetryOnResponse( + shouldRetryOnResponse != nullptr + ? shouldRetryOnResponse + : [&](RawResponse const& response, auto options, auto attempt, auto retryAfter, auto jitter) { + retryAfter = std::chrono::milliseconds(0); + auto ignore = decltype(retryAfter)(); + return RetryPolicy::ShouldRetryOnResponse( + response, options, attempt, ignore, jitter); + }) { } @@ -717,3 +734,79 @@ TEST(RetryPolicy, RetryAfter) EXPECT_EQ(retryAfter, 90s); } } + +TEST(RetryPolicy, LogMessages) +{ + using Azure::Core::Diagnostics::Logger; + + struct Log + { + struct Entry + { + Logger::Level Level; + std::string Message; + }; + + std::vector Entries; + + Log() + { + Logger::SetLevel(Logger::Level::Informational); + Logger::SetListener([&](auto lvl, auto msg) { Entries.emplace_back(Entry{lvl, msg}); }); + } + + ~Log() + { + Logger::SetListener(nullptr); + Logger::SetLevel(Logger::Level::Warning); + } + + } log; + + { + using namespace std::chrono_literals; + RetryOptions const retryOptions{5, 10s, 5min, {HttpStatusCode::InternalServerError}}; + + auto requestNumber = 0; + + std::vector> policies; + policies.emplace_back(std::make_unique(retryOptions, nullptr, nullptr)); + policies.emplace_back(std::make_unique([&]() { + ++requestNumber; + + if (requestNumber == 1) + { + throw TransportException("Cable Unplugged"); + } + + return std::make_unique( + 1, + 1, + requestNumber == 2 ? HttpStatusCode::InternalServerError + : HttpStatusCode::ServiceUnavailable, + "Test"); + })); + + Azure::Core::Http::_internal::HttpPipeline pipeline(policies); + + Request request(HttpMethod::Get, Azure::Core::Url("https://www.microsoft.com")); + pipeline.Send(request, Azure::Core::Context()); + } + + EXPECT_EQ(log.Entries.size(), 5); + + EXPECT_EQ(log.Entries[0].Level, Logger::Level::Warning); + EXPECT_EQ(log.Entries[0].Message, "HTTP Transport error: Cable Unplugged"); + + EXPECT_EQ(log.Entries[1].Level, Logger::Level::Informational); + EXPECT_EQ(log.Entries[1].Message, "HTTP Retry attempt #1 will be made in 0ms."); + + EXPECT_EQ(log.Entries[2].Level, Logger::Level::Informational); + EXPECT_EQ(log.Entries[2].Message, "HTTP status code 500 will be retried."); + + EXPECT_EQ(log.Entries[3].Level, Logger::Level::Informational); + EXPECT_EQ(log.Entries[3].Message, "HTTP Retry attempt #2 will be made in 0ms."); + + EXPECT_EQ(log.Entries[4].Level, Logger::Level::Warning); + EXPECT_EQ(log.Entries[4].Message, "HTTP status code 503 won't be retried."); +} diff --git a/sdk/core/azure-core/test/ut/sha_test.cpp b/sdk/core/azure-core/test/ut/sha_test.cpp index 5cab15ec0..32bb33a26 100644 --- a/sdk/core/azure-core/test/ut/sha_test.cpp +++ b/sdk/core/azure-core/test/ut/sha_test.cpp @@ -18,3 +18,27 @@ TEST(SHA, SHA256Test) for (size_t i = 0; i != shaResult.size(); i++) printf("%02x", shaResult[i]); } + +TEST(SHA, SHA384Test) +{ + Sha384Hash sha; + Sha384Hash sha2; + uint8_t data[] = "A"; + auto shaResult = sha.Final(data, sizeof(data)); + auto shaResult2 = sha2.Final(data, sizeof(data)); + EXPECT_EQ(shaResult, shaResult2); + for (size_t i = 0; i != shaResult.size(); i++) + printf("%02x", shaResult[i]); +} + +TEST(SHA, SHA512Test) +{ + Sha512Hash sha; + Sha512Hash sha2; + uint8_t data[] = "A"; + auto shaResult = sha.Final(data, sizeof(data)); + auto shaResult2 = sha2.Final(data, sizeof(data)); + EXPECT_EQ(shaResult, shaResult2); + for (size_t i = 0; i != shaResult.size(); i++) + printf("%02x", shaResult[i]); +} diff --git a/sdk/core/azure-core/test/ut/url_test.cpp b/sdk/core/azure-core/test/ut/url_test.cpp index c1ca10cce..a15a715b0 100644 --- a/sdk/core/azure-core/test/ut/url_test.cpp +++ b/sdk/core/azure-core/test/ut/url_test.cpp @@ -312,4 +312,22 @@ namespace Azure { namespace Core { namespace Test { EXPECT_EQ(url1.GetPath(), "x/y"); EXPECT_EQ(url2.GetPath(), "x/y"); } + + TEST(URL, Decode) + { + EXPECT_EQ(Core::Url::Decode("+%61b"), " ab"); + EXPECT_THROW(Core::Url::Decode("%"), std::runtime_error); + EXPECT_THROW(Core::Url::Decode("%GA"), std::runtime_error); + EXPECT_THROW(Core::Url::Decode("%AG"), std::runtime_error); + } + + TEST(URL, AppendQueryParameters) + { + Core::Url url("http://www.microsoft.com??param=value"); + auto params = url.GetQueryParameters(); + + EXPECT_EQ(params.size(), 1); + EXPECT_NE(params.find("param"), params.end()); + EXPECT_EQ(params["param"], "value"); + } }}} // namespace Azure::Core::Test diff --git a/sdk/core/ci.yml b/sdk/core/ci.yml index 565eaa1eb..83a04e314 100644 --- a/sdk/core/ci.yml +++ b/sdk/core/ci.yml @@ -43,8 +43,8 @@ stages: CtestExcludeRegex: azure-storage|azure-identity-livetest LiveTestCtestRegex: '"azure-core.|json-test"' LiveTestTimeoutInMinutes: 90 # default is 60 min. We need a little longer on worst case for Win+jsonTests - LineCoverageTarget: 81 - BranchCoverageTarget: 43 + LineCoverageTarget: 93 + BranchCoverageTarget: 55 Artifacts: - Name: azure-core Path: azure-core