Fault injection test (#2265)
* missing line for single docs * format * fault injection test * winHttp * storage blobs client with fault injector
This commit is contained in:
parent
af936e052f
commit
e4a18b5eb3
@ -170,6 +170,7 @@ if(BUILD_TESTING)
|
||||
if(DEFINED ENV{AZURE_CORE_ENABLE_JSON_TESTS})
|
||||
add_subdirectory(test/nlohmann-json-test)
|
||||
endif()
|
||||
add_subdirectory(test/fault-injector)
|
||||
endif()
|
||||
|
||||
if (BUILD_PERFORMANCE_TESTS)
|
||||
|
||||
17
sdk/core/azure-core/test/fault-injector/CMakeLists.txt
Normal file
17
sdk/core/azure-core/test/fault-injector/CMakeLists.txt
Normal file
@ -0,0 +1,17 @@
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
cmake_minimum_required (VERSION 3.13)
|
||||
|
||||
set(azure-core-test-fault-injector)
|
||||
|
||||
project (azure-core-test-fault-injector LANGUAGES CXX)
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
|
||||
add_executable (
|
||||
azure-core-test-fault-injector
|
||||
main.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(azure-core-test-fault-injector PRIVATE azure-core)
|
||||
106
sdk/core/azure-core/test/fault-injector/main.cpp
Normal file
106
sdk/core/azure-core/test/fault-injector/main.cpp
Normal file
@ -0,0 +1,106 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
/**
|
||||
* @brief Validates the Azure Core transport adapters with fault responses from server.
|
||||
*
|
||||
* @note This test requires the Http-fault-injector
|
||||
* (https://github.com/Azure/azure-sdk-tools/tree/master/tools/http-fault-injector) running. Follow
|
||||
* the instructions to install and run the server before running this test.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <azure/core.hpp>
|
||||
|
||||
#if defined(BUILD_CURL_HTTP_TRANSPORT_ADAPTER)
|
||||
#include <azure/core/http/curl_transport.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BUILD_TRANSPORT_WINHTTP_ADAPTER)
|
||||
#include "azure/core/http/win_http_transport.hpp"
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* @brief The options to set the #FaultInjectionClient behavior like the injection server and the
|
||||
* http client implementation to use.
|
||||
*
|
||||
*/
|
||||
struct FaultInjectionClientOptions
|
||||
{
|
||||
Azure::Core::Url m_url;
|
||||
std::shared_ptr<Azure::Core::Http::HttpTransport> m_transport;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief An special http policy to redirect requests to the Fault injector server.
|
||||
*
|
||||
*/
|
||||
class FaultInjectionClient : public Azure::Core::Http::HttpTransport {
|
||||
private:
|
||||
FaultInjectionClientOptions m_options;
|
||||
|
||||
public:
|
||||
FaultInjectionClient(FaultInjectionClientOptions options) : m_options(std::move(options)) {}
|
||||
|
||||
std::unique_ptr<Azure::Core::Http::RawResponse> Send(
|
||||
Azure::Core::Http::Request& request,
|
||||
Azure::Core::Context const& context) override
|
||||
{
|
||||
auto redirectRequest = Azure::Core::Http::Request(
|
||||
request.GetMethod(), Azure::Core::Url(m_options.m_url.GetAbsoluteUrl()));
|
||||
for (auto& header : request.GetHeaders())
|
||||
{
|
||||
redirectRequest.SetHeader(header.first, header.second);
|
||||
}
|
||||
|
||||
{
|
||||
auto& url = request.GetUrl();
|
||||
auto port = url.GetPort();
|
||||
redirectRequest.SetHeader(
|
||||
"Host", url.GetHost() + (port != 0 ? ":" + std::to_string(port) : ""));
|
||||
}
|
||||
|
||||
return m_options.m_transport->Send(redirectRequest, context);
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
/* The transport adapter must allow insecure SSL certs.
|
||||
If both curl and winHttp are available, curl is preferred for this test.for*/
|
||||
#if defined(BUILD_CURL_HTTP_TRANSPORT_ADAPTER)
|
||||
Azure::Core::Http::CurlTransportOptions curlOptions;
|
||||
curlOptions.SslVerifyPeer = false;
|
||||
auto implementationClient = std::make_shared<Azure::Core::Http::CurlTransport>(curlOptions);
|
||||
|
||||
#elif (BUILD_TRANSPORT_WINHTTP_ADAPTER)
|
||||
// TODO: make winHTTP to support insecure SSL certs
|
||||
Azure::Core::Http::WinHttpTransportOptions winHttpOptions;
|
||||
auto implementationClient = std::make_shared<Azure::Core::Http::WinHttpTransport>(winHttpOptions);
|
||||
#endif
|
||||
|
||||
FaultInjectionClientOptions options;
|
||||
options.m_url = Azure::Core::Url("https://localhost:7778");
|
||||
options.m_transport = implementationClient;
|
||||
FaultInjectionClient client(options);
|
||||
|
||||
std::cout << "Sending request..." << std::endl;
|
||||
|
||||
Azure::Core::Context context;
|
||||
auto request = Azure::Core::Http::Request(
|
||||
Azure::Core::Http::HttpMethod::Get, Azure::Core::Url("https://www.example.org"));
|
||||
auto response = client.Send(request, context);
|
||||
// Make sure to pull all bytes from network.
|
||||
auto body = response->ExtractBodyStream()->ReadToEnd();
|
||||
|
||||
std::cout << "Status Code: "
|
||||
<< static_cast<typename std::underlying_type<Azure::Core::Http::HttpStatusCode>::type>(
|
||||
response->GetStatusCode())
|
||||
<< std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -104,6 +104,8 @@ if(BUILD_TESTING)
|
||||
)
|
||||
|
||||
target_link_libraries(azure-storage-test PRIVATE azure-storage-blobs)
|
||||
|
||||
add_subdirectory(test/fault-injector)
|
||||
endif()
|
||||
|
||||
if(BUILD_STORAGE_SAMPLES)
|
||||
|
||||
@ -0,0 +1,17 @@
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
cmake_minimum_required (VERSION 3.13)
|
||||
|
||||
set(azure-storage-blobs-test-fault-injector)
|
||||
|
||||
project (azure-storage-blobs-test-fault-injector LANGUAGES CXX)
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
|
||||
add_executable (
|
||||
azure-storage-blobs-test-fault-injector
|
||||
main.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(azure-storage-blobs-test-fault-injector PRIVATE azure-storage-blobs)
|
||||
113
sdk/storage/azure-storage-blobs/test/fault-injector/main.cpp
Normal file
113
sdk/storage/azure-storage-blobs/test/fault-injector/main.cpp
Normal file
@ -0,0 +1,113 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
/**
|
||||
* @brief Validates the Azure Storage blobs SDK client with fault responses from server.
|
||||
*
|
||||
* @note This test requires the Http-fault-injector
|
||||
* (https://github.com/Azure/azure-sdk-tools/tree/master/tools/http-fault-injector) running. Follow
|
||||
* the instructions to install and run the server before running this test.
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
// For using std::getenv()
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#include <azure/storage/blobs.hpp>
|
||||
|
||||
#if defined(BUILD_CURL_HTTP_TRANSPORT_ADAPTER)
|
||||
#include <azure/core/http/curl_transport.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BUILD_TRANSPORT_WINHTTP_ADAPTER)
|
||||
#include "azure/core/http/win_http_transport.hpp"
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* @brief The options to set the #FaultInjectionClient behavior like the injection server and the
|
||||
* http client implementation to use.
|
||||
*
|
||||
*/
|
||||
struct FaultInjectionClientOptions
|
||||
{
|
||||
Azure::Core::Url m_url;
|
||||
std::shared_ptr<Azure::Core::Http::HttpTransport> m_transport;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief An special http policy to redirect requests to the Fault injector server.
|
||||
*
|
||||
*/
|
||||
class FaultInjectionClient : public Azure::Core::Http::HttpTransport {
|
||||
private:
|
||||
FaultInjectionClientOptions m_options;
|
||||
|
||||
public:
|
||||
FaultInjectionClient(FaultInjectionClientOptions options) : m_options(std::move(options)) {}
|
||||
|
||||
std::unique_ptr<Azure::Core::Http::RawResponse> Send(
|
||||
Azure::Core::Http::Request& request,
|
||||
Azure::Core::Context const& context) override
|
||||
{
|
||||
auto redirectRequest = Azure::Core::Http::Request(
|
||||
request.GetMethod(), Azure::Core::Url(m_options.m_url.GetAbsoluteUrl()));
|
||||
for (auto& header : request.GetHeaders())
|
||||
{
|
||||
redirectRequest.SetHeader(header.first, header.second);
|
||||
}
|
||||
|
||||
{
|
||||
auto& url = request.GetUrl();
|
||||
auto port = url.GetPort();
|
||||
redirectRequest.SetHeader(
|
||||
"Host", url.GetHost() + (port != 0 ? ":" + std::to_string(port) : ""));
|
||||
}
|
||||
|
||||
return m_options.m_transport->Send(redirectRequest, context);
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
/* The transport adapter must allow insecure SSL certs.
|
||||
If both curl and winHttp are available, curl is preferred for this test.for*/
|
||||
#if defined(BUILD_CURL_HTTP_TRANSPORT_ADAPTER)
|
||||
Azure::Core::Http::CurlTransportOptions curlOptions;
|
||||
curlOptions.SslVerifyPeer = false;
|
||||
auto implementationClient = std::make_shared<Azure::Core::Http::CurlTransport>(curlOptions);
|
||||
|
||||
#elif (BUILD_TRANSPORT_WINHTTP_ADAPTER)
|
||||
// TODO: make winHTTP to support insecure SSL certs
|
||||
Azure::Core::Http::WinHttpTransportOptions winHttpOptions;
|
||||
auto implementationClient = std::make_shared<Azure::Core::Http::WinHttpTransport>(winHttpOptions);
|
||||
#endif
|
||||
|
||||
std::string connectionString(std::getenv("STORAGE_CONNECTION_STRING"));
|
||||
|
||||
// Set the options for the FaultInjectorClient
|
||||
FaultInjectionClientOptions options;
|
||||
options.m_url = Azure::Core::Url("https://localhost:7778");
|
||||
options.m_transport = implementationClient;
|
||||
|
||||
// Set the FaultInjectorClient as the transport adapter for the blobs client.
|
||||
Azure::Storage::Blobs::BlobClientOptions blobClientOptions;
|
||||
blobClientOptions.Transport.Transport = std::make_shared<FaultInjectionClient>(options);
|
||||
|
||||
auto blobClient = Azure::Storage::Blobs::BlobClient::CreateFromConnectionString(
|
||||
connectionString, "sample", "sample.txt", blobClientOptions);
|
||||
|
||||
std::cout << "Sending request..." << std::endl;
|
||||
|
||||
auto response = blobClient.Download();
|
||||
auto content = response.Value.BodyStream->ReadToEnd();
|
||||
|
||||
std::cout << "Content: " << std::string(content.begin(), content.end()) << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user