Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stress test #3820

Merged
merged 19 commits into from
Jul 13, 2022
Merged
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
[Rr]eleases/
x64/
x86/
bld/
bld*/
gearama marked this conversation as resolved.
Show resolved Hide resolved
[Bb]in/
[Oo]bj/
[Ll]og/
Expand Down
1 change: 1 addition & 0 deletions sdk/core/azure-core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
26 changes: 26 additions & 0 deletions sdk/core/azure-core/test/libcurl-stress-test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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()
15 changes: 15 additions & 0 deletions sdk/core/azure-core/test/libcurl-stress-test/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
FROM mcr.microsoft.com/mirror/docker/library/ubuntu:22.04
gearama marked this conversation as resolved.
Show resolved Hide resolved

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
Original file line number Diff line number Diff line change
@@ -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>
gearama marked this conversation as resolved.
Show resolved Hide resolved
#include <fstream>
#include <ios>
#include <iostream>
#include <memory>
#include <stdlib.h>
#include <string>
#include <vector>
gearama marked this conversation as resolved.
Show resolved Hide resolved

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*/
gearama marked this conversation as resolved.
Show resolved Hide resolved
#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)
gearama marked this conversation as resolved.
Show resolved Hide resolved
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);
gearama marked this conversation as resolved.
Show resolved Hide resolved
// auto deadline = std::chrono::system_clock::now() + duration;
gearama marked this conversation as resolved.
Show resolved Hide resolved
auto request
= Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Get, Azure::Core::Url(target));
auto response = implementationClient->Send(request, context); //.WithDeadline(deadline));
gearama marked this conversation as resolved.
Show resolved Hide resolved
// Make sure to pull all bytes from network.
auto body = response->ExtractBodyStream()->ReadToEnd();
}
catch (std::exception const&)
{
gearama marked this conversation as resolved.
Show resolved Hide resolved
}
}

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
gearama marked this conversation as resolved.
Show resolved Hide resolved
{
(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;
}