Skip to content

Commit

Permalink
add test checking for memory leaks using crt mem tracer
Browse files Browse the repository at this point in the history
  • Loading branch information
sbiscigl committed Aug 15, 2024
1 parent e09d241 commit 4d649fb
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 37 deletions.
89 changes: 52 additions & 37 deletions tests/aws-cpp-sdk-s3-crt-integration-tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,37 +1,52 @@
add_project(aws-cpp-sdk-s3-crt-integration-tests
"Tests for the AWS S3 CRT C++ SDK"
aws-cpp-sdk-s3-crt
testing-resources
aws-cpp-sdk-core)

file(GLOB AWS_S3_CRT_SRC
"${CMAKE_CURRENT_SOURCE_DIR}/*.cpp"
)

file(GLOB AWS_S3_CRT_INTEGRATION_TESTS_SRC
${AWS_S3_CRT_SRC}
)

add_definitions(-DRESOURCES_DIR="${CMAKE_CURRENT_SOURCE_DIR}/resources")

if(MSVC AND BUILD_SHARED_LIBS)
add_definitions(-DGTEST_LINKED_AS_SHARED_LIBRARY=1)
endif()

enable_testing()

if(PLATFORM_ANDROID AND BUILD_SHARED_LIBS)
add_library(${PROJECT_NAME} ${AWS_S3_CRT_INTEGRATION_TESTS_SRC})
else()
add_executable(${PROJECT_NAME} ${AWS_S3_CRT_INTEGRATION_TESTS_SRC})
endif()

set_compiler_flags(${PROJECT_NAME})
set_compiler_warnings(${PROJECT_NAME})

target_link_libraries(${PROJECT_NAME} ${PROJECT_LIBS})

if(MSVC AND BUILD_SHARED_LIBS)
set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "/DELAYLOAD:aws-cpp-sdk-s3-crt.dll /DELAYLOAD:aws-cpp-sdk-core.dll")
target_link_libraries(${PROJECT_NAME} delayimp.lib)
endif()
set(TEST_LIST "aws-cpp-sdk-s3-crt-integration-tests:RunTests.cpp")

# Only run memlimiter test if we are building with custom memory management
if (CUSTOM_MEMORY_MANAGEMENT)
list(APPEND TEST_LIST "aws-cpp-sdk-s3-crt-memory-checked-integration-tests:RunTestsWithMemTracer.cpp")
endif ()

foreach(TEST IN LISTS TEST_LIST)
string(REPLACE ":" ";" TEST_ITEMS "${TEST}")
list(GET TEST_ITEMS 0 TEST_PROJECT_NAME)
list(GET TEST_ITEMS 1 TEST_MAIN_FILE)

add_project("${TEST_PROJECT_NAME}"
"Tests for the AWS S3 CRT C++ SDK"
aws-cpp-sdk-s3-crt
testing-resources
aws-cpp-sdk-core)

file(GLOB AWS_S3_CRT_SRC
"${TEST_MAIN_FILE}"
"BucketAndObjectOperationTest.cpp"
"S3ExpressTest.cpp"
)

file(GLOB AWS_S3_CRT_INTEGRATION_TESTS_SRC
${AWS_S3_CRT_SRC}
)

add_definitions(-DRESOURCES_DIR="${CMAKE_CURRENT_SOURCE_DIR}/resources")

if(MSVC AND BUILD_SHARED_LIBS)
add_definitions(-DGTEST_LINKED_AS_SHARED_LIBRARY=1)
endif()

enable_testing()

if(PLATFORM_ANDROID AND BUILD_SHARED_LIBS)
add_library(${PROJECT_NAME} ${AWS_S3_CRT_INTEGRATION_TESTS_SRC})
else()
add_executable(${PROJECT_NAME} ${AWS_S3_CRT_INTEGRATION_TESTS_SRC})
endif()

set_compiler_flags(${PROJECT_NAME})
set_compiler_warnings(${PROJECT_NAME})

target_link_libraries(${PROJECT_NAME} ${PROJECT_LIBS})

if(MSVC AND BUILD_SHARED_LIBS)
set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "/DELAYLOAD:aws-cpp-sdk-s3-crt.dll /DELAYLOAD:aws-cpp-sdk-core.dll")
target_link_libraries(${PROJECT_NAME} delayimp.lib)
endif()
endforeach ()
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/

#include <gtest/gtest.h>
#include <aws/core/Aws.h>
#include <aws/testing/platform/PlatformTesting.h>
#include <aws/testing/TestingEnvironment.h>
#include <aws/testing/MemoryTesting.h>

int main(int argc, char** argv) {
Aws::Testing::SetDefaultSigPipeHandler();
Aws::SDKOptions options;
options.loggingOptions.logLevel = Aws::Utils::Logging::LogLevel::Trace;
CRTMemTracerMemorySystem memorySystem{};
options.memoryManagementOptions.memoryManager = &memorySystem;
Aws::Testing::InitPlatformTest(options);
Aws::Testing::ParseArgs(argc, argv);

Aws::InitAPI(options);
::testing::InitGoogleTest(&argc, argv);
int exitCode = RUN_ALL_TESTS();

Aws::ShutdownAPI(options);
memorySystem.AssertNoLeaks();
Aws::Testing::ShutdownPlatformTest(options);
return exitCode;
}
15 changes: 15 additions & 0 deletions tests/testing-resources/include/aws/testing/MemoryTesting.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@

#include <aws/core/utils/memory/MemorySystemInterface.h>
#include <aws/core/utils/memory/AWSMemory.h>
#include <aws/common/allocator.h>

#include <stdint.h>
#include <algorithm>
#include <mutex>
#include <atomic>
#include <cstdlib>
#include <functional>

// Could be folded into ExactTestMemorySystem, tracks some aggregate stats
class AWS_TESTING_API BaseTestMemorySystem : public Aws::Utils::Memory::MemorySystemInterface
Expand Down Expand Up @@ -108,6 +110,19 @@ class AWS_TESTING_API ExactTestMemorySystem : public BaseTestMemorySystem

};

class AWS_TESTING_API CRTMemTracerMemorySystem : public Aws::Utils::Memory::MemorySystemInterface
{
public:
CRTMemTracerMemorySystem();
void Begin() override {}
void End() override {}
void* AllocateMemory(std::size_t blockSize, std::size_t alignment, const char* allocationTag) override;
void FreeMemory(void* memoryPtr) override;
void AssertNoLeaks();
private:
std::unique_ptr<aws_allocator, std::function<void (aws_allocator*)>> mem_tracer_;
};

#ifdef USE_AWS_MEMORY_MANAGEMENT

// Utility macros to put at the start and end of tests
Expand Down
30 changes: 30 additions & 0 deletions tests/testing-resources/source/MemoryTesting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,36 @@ void ExactTestMemorySystem::Cleanup()
free(m_buckets);
}

CRTMemTracerMemorySystem::CRTMemTracerMemorySystem():
mem_tracer_{
aws_mem_tracer_new(
aws_default_allocator(),
nullptr,
AWS_MEMTRACE_STACKS,
10),
aws_mem_tracer_destroy}
{}

void* CRTMemTracerMemorySystem::AllocateMemory(std::size_t blockSize, std::size_t alignment, const char* allocationTag)
{
AWS_UNREFERENCED_PARAM(alignment);
AWS_UNREFERENCED_PARAM(allocationTag);
return aws_mem_acquire(mem_tracer_.get(), blockSize);
}

void CRTMemTracerMemorySystem::FreeMemory(void* memoryPtr)
{
aws_mem_release(mem_tracer_.get(), memoryPtr);
}

void CRTMemTracerMemorySystem::AssertNoLeaks()
{
const size_t leaked_allocations = aws_mem_tracer_count(mem_tracer_.get());
const size_t leaked_bytes = aws_mem_tracer_bytes(mem_tracer_.get());
EXPECT_EQ(0ul, leaked_allocations);
EXPECT_EQ(0ul, leaked_bytes);
}

void ExactTestMemorySystem::GrowFreePool()
{
// malloc enough memory to hold the linked list pointer as well as the desired number of TaggedMemoryTrackers
Expand Down
11 changes: 11 additions & 0 deletions tools/scripts/run_integration_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,17 @@ def main():
"aws-cpp-sdk-ec2-integration-tests",
"aws-cpp-sdk-timestream-query-integration-tests"]

# check for existence of these binaries before adding them to tests
# as they will not always be present
cmake_dependent_tests = [
"aws-cpp-sdk-s3-crt-memory-checked-integration-tests"
]

for test in cmake_dependent_tests:
test_exe = os.path.join(arguments["testDir"], test if test_has_parent_dir else "", test) + exe_extension
if os.path.isfile(test_exe):
test_list.append("aws-cpp-sdk-s3-crt-memory-checked-integration-tests")

random.shuffle(test_list)

for testName in test_list:
Expand Down

0 comments on commit 4d649fb

Please sign in to comment.