Stress test (#3820)

* mem leak fix

* PR comments fix

* PR comments

* seems to work?

* clang

* curl again

* add first stress test

* also update gitignore

* missing line

* only linux

* clang typo format

* typo 2

* PR comments

* cspell

* remove terminator
This commit is contained in:
George Arama 2022-07-13 13:11:50 -07:00 committed by GitHub
parent 12f52838c7
commit e0706ba1fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 138 additions and 1 deletions

2
.gitignore vendored
View File

@ -19,7 +19,7 @@
[Rr]eleases/
x64/
x86/
bld/
bld*/
[Bb]in/
[Oo]bj/
[Ll]og/

View File

@ -204,6 +204,7 @@ if(BUILD_TESTING)
add_subdirectory(test/nlohmann-json-test)
endif()
add_subdirectory(test/fault-injector)
add_subdirectory(test/libcurl-stress-test)
endif()
if (BUILD_PERFORMANCE_TESTS)

View File

@ -0,0 +1,26 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# SPDX-License-Identifier: MIT
cmake_minimum_required(VERSION 3.13)
project(azure-core-libcurl-stress-test LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED True)
add_executable(
azure-core-libcurl-stress-test
libcurl_stress_test.cpp
)
target_link_libraries(azure-core-libcurl-stress-test PRIVATE azure-core)
create_map_file(azure-core-libcurl-stress-test azure-core-libcurl-stress-test.map)
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/Dockerfile
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/)
find_program(DOCKER_EXECUTABLE docker)
#if docker is found try to build the docker image in the defined docker_build stage which should be run after build
if(DOCKER_EXECUTABLE)
add_custom_target(docker_build
COMMAND ${DOCKER_EXECUTABLE} build --build-arg targetTest=azure-core-libcurl-stress-test --build-arg build=on --tag=azuresdkforcpp/curlstress -f Dockerfile .)
endif()

View File

@ -0,0 +1,15 @@
FROM mcr.microsoft.com/mirror/docker/library/ubuntu:22.04
ARG targetTest
ARG build
# copy the tagrget binary
ADD $targetTest ./$targetTest
RUN chmod +x ./$targetTest
# install the mem check tool
RUN apt-get update -y
RUN apt-get install valgrind -y
# execute under memcheck tool
RUN valgrind --tool=memcheck -s ./$targetTest $build

View File

@ -0,0 +1,95 @@
// 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/main/tools/http-fault-injector) running. Follow
* the instructions to install and run the server before running this test.
*
*/
#define REQUESTS 100
#define WARMUP 100
#define ROUNDS 100
#include <azure/core.hpp>
#include <azure/core/http/curl_transport.hpp>
#include <fstream>
#include <ios>
#include <iostream>
#include <memory>
#include <stdlib.h>
#include <string>
#include <vector>
void SendRequest(std::string target)
{
std::cout << target << std::endl;
/* 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)
Azure::Core::Http::WinHttpTransportOptions winHttpOptions;
auto implementationClient = std::make_shared<Azure::Core::Http::WinHttpTransport>(winHttpOptions);
#endif
try
{
Azure::Core::Context context;
// auto duration = std::chrono::milliseconds(1000);
// auto deadline = std::chrono::system_clock::now() + duration;
auto request
= Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Get, Azure::Core::Url(target));
auto response = implementationClient->Send(request, context); //.WithDeadline(deadline));
// Make sure to pull all bytes from network.
auto body = response->ExtractBodyStream()->ReadToEnd();
}
catch (std::exception const&)
{
}
}
void Operation(int repetitions)
{
std::string base = "https://xyz.";
for (int i = 0; i < repetitions; i++)
{
std::cout << i << std::endl;
SendRequest(base + std::to_string(i) + ".abc");
}
}
int main(int argc, char** argv) // i can have either 0 or 2 params here
{
(void)argv; // to get rid of the unused warning
// some param was passed to the program , which happens only in build mode, not run of the docker
// file. thus we will run a quick test to make sure the executable runs.
if (argc != 1)
{
std::cout << "--------------\tBUILD TEST\t--------------" << std::endl;
Operation(5);
std::cout << "--------------\tEND BUILD TEST\t--------------" << std::endl;
return 0;
}
std::cout << "--------------\tSTARTING TEST\t--------------" << std::endl;
std::cout << "--------------\tPRE WARMUP\t--------------" << std::endl;
Operation(WARMUP);
std::cout << "--------------\tPOST WARMUP\t--------------" << std::endl;
for (int i = 0; i < ROUNDS; i++)
{
std::cout << "--------------\tTEST ITERATION:" << i << "\t--------------" << std::endl;
Operation(REQUESTS);
std::cout << "--------------\tDONE ITERATION:" << i << "\t--------------" << std::endl;
}
return 0;
}