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:
Victor Vazquez 2021-05-17 10:34:50 -07:00 committed by GitHub
parent af936e052f
commit e4a18b5eb3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 256 additions and 0 deletions

View File

@ -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)

View 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)

View 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;
}

View File

@ -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)

View File

@ -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)

View 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;
}