diff --git a/sdk/core/azure-core/test/perf/CMakeLists.txt b/sdk/core/azure-core/test/perf/CMakeLists.txt index 167e77ae3a..4f962c16d7 100644 --- a/sdk/core/azure-core/test/perf/CMakeLists.txt +++ b/sdk/core/azure-core/test/perf/CMakeLists.txt @@ -9,6 +9,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED True) set( AZURE_CORE_PERF_TEST_HEADER + inc/azure/core/test/http_transport_test.hpp inc/azure/core/test/nullable_test.hpp inc/azure/core/test/uuid_test.hpp ) diff --git a/sdk/core/azure-core/test/perf/inc/azure/core/test/http_transport_test.hpp b/sdk/core/azure-core/test/perf/inc/azure/core/test/http_transport_test.hpp new file mode 100644 index 0000000000..ee0a15e300 --- /dev/null +++ b/sdk/core/azure-core/test/perf/inc/azure/core/test/http_transport_test.hpp @@ -0,0 +1,150 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +/** + * @file + * @brief Test the HTTP send performance. + * + */ + +#pragma once + +#include "../../../core/perf/inc/azure/perf.hpp" + +#include +#if defined(BUILD_CURL_HTTP_TRANSPORT_ADAPTER) +#include +#endif +#if defined(BUILD_TRANSPORT_WINHTTP_ADAPTER) +#include +#endif + +#include + +namespace Azure { namespace Core { namespace Test { + + /** + * @brief Measure the HTTP transport performance. + */ + class HTTPTransportTest : public Azure::Perf::PerfTest { + + std::string m_target; + std::shared_ptr m_transport; + Azure::Core::Http::HttpMethod m_httpMethod = Azure::Core::Http::HttpMethod::Get; + + void GetRequest() const + { + auto httpRequest = Azure::Core::Http::Request(m_httpMethod, Azure::Core::Url(m_target)); + Azure::Core::Context context; + auto response = m_transport->Send(httpRequest, context); + // Make sure to pull all bytes from network. + auto body = response->ExtractBodyStream()->ReadToEnd(); + } + + void PostRequest() const + { + std::string payload = "{}"; + Azure::Core::IO::MemoryBodyStream payloadStream( + reinterpret_cast(payload.data()), payload.size()); + auto httpRequest + = Azure::Core::Http::Request(m_httpMethod, Azure::Core::Url(m_target), &payloadStream); + Azure::Core::Context context; + auto response = m_transport->Send(httpRequest, context); + // Make sure to pull all bytes from network. + auto body = response->ExtractBodyStream()->ReadToEnd(); + } + + public: + /** + * @brief Construct a new HTTPTransportTest test. + * + * @param options The test options. + */ + HTTPTransportTest(Azure::Perf::TestOptions options) : PerfTest(options) {} + + void Setup() override + { +#if defined(BUILD_TRANSPORT_WINHTTP_ADAPTER) + if ("winhttp" == m_options.GetMandatoryOption("Transport")) + { + + Azure::Core::Http::WinHttpTransportOptions transportOptions; + transportOptions.IgnoreInvalidCertificateCommonName = true; + transportOptions.IgnoreUnknownCertificateAuthority = true; + m_transport = std::make_shared(transportOptions); + } +#endif +#if defined(BUILD_CURL_HTTP_TRANSPORT_ADAPTER) + if ("curl" == m_options.GetMandatoryOption("Transport")) + { + + Azure::Core::Http::CurlTransportOptions transportOptions; + transportOptions.SslVerifyPeer = false; + m_transport = std::make_shared(transportOptions); + } +#endif + m_httpMethod + = Azure::Core::Http::HttpMethod(m_options.GetMandatoryOption("Method")); + + if (m_httpMethod == Azure::Core::Http::HttpMethod::Get) + { + m_target = GetTestProxy() + "/Admin/isAlive"; + } + else if (m_httpMethod == Azure::Core::Http::HttpMethod::Post) + { + m_target = GetTestProxy() + "/Admin/setRecordingOptions"; + } + } + + /** + * @brief Use HTTPTransportTest to call test proxy endpoint. + * + */ + void Run(Azure::Core::Context const&) override + { + try + { + if (m_httpMethod == Azure::Core::Http::HttpMethod::Get) + { + GetRequest(); + } + else if (m_httpMethod == Azure::Core::Http::HttpMethod::Post) + { + PostRequest(); + } + } + catch (std::exception const&) + { + // don't print exceptions, they are happening at each request, this is the point of the test + } + } + + /** + * @brief Define the test options for the test. + * + * @return The list of test options. + */ + std::vector GetTestOptions() override + { + return { + {"Method", {"--method"}, "The HTTP method e.g. GET, POST etc.", 1, true}, + {"Transport", {"--transport"}, "The HTTP Transport curl/winhttp.", 1, true}}; + } + + /** + * @brief Get the static Test Metadata for the test. + * + * @return Azure::Perf::TestMetadata describing the test. + */ + static Azure::Perf::TestMetadata GetTestMetadata() + { + return { + "HTTPTransportTest", + "Measures HTTP transport performance", + [](Azure::Perf::TestOptions options) { + return std::make_unique(options); + }}; + } + }; + +}}} // namespace Azure::Core::Test diff --git a/sdk/core/azure-core/test/perf/src/azure_core_perf_test.cpp b/sdk/core/azure-core/test/perf/src/azure_core_perf_test.cpp index 6c29232c20..7ea82309ba 100644 --- a/sdk/core/azure-core/test/perf/src/azure_core_perf_test.cpp +++ b/sdk/core/azure-core/test/perf/src/azure_core_perf_test.cpp @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +#include "azure/core/test/http_transport_test.hpp" #include "azure/core/test/nullable_test.hpp" #include "azure/core/test/uuid_test.hpp" @@ -13,6 +14,7 @@ int main(int argc, char** argv) // Create the test list std::vector tests{ + Azure::Core::Test::HTTPTransportTest::GetTestMetadata(), Azure::Core::Test::NullableTest::GetTestMetadata(), Azure::Core::Test::UuidTest::GetTestMetadata()}; diff --git a/sdk/core/perf/inc/azure/perf/base_test.hpp b/sdk/core/perf/inc/azure/perf/base_test.hpp index 19816c332e..bdec167ed1 100644 --- a/sdk/core/perf/inc/azure/perf/base_test.hpp +++ b/sdk/core/perf/inc/azure/perf/base_test.hpp @@ -170,5 +170,10 @@ namespace Azure { namespace Perf { ConfigureClientOptions(options); return options; } + + /** + * @brief Returns the test proxy. + */ + std::string GetTestProxy() const { return m_proxy; } }; }} // namespace Azure::Perf