From e3e9e096a0fa4537e35f32c4ea10ea62fe7c9f5a Mon Sep 17 00:00:00 2001 From: Maxi Mittelhammer Date: Thu, 2 Feb 2023 17:58:46 +0100 Subject: [PATCH 01/10] Changed sprintf to snprintf (#180) --- src/runtime.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/runtime.cpp b/src/runtime.cpp index 3968adb..4ca70dc 100644 --- a/src/runtime.cpp +++ b/src/runtime.cpp @@ -496,7 +496,7 @@ static std::string json_escape(std::string const& in) // escape and print as unicode codepoint constexpr int printed_unicode_length = 6; // 4 hex + letter 'u' + \0 std::array buf; - sprintf(buf.data(), "u%04x", ch); + snprintf(buf.data(), buf.size(), "u%04x", ch); out.append(buf.data(), buf.size() - 1); // add only five, discarding the null terminator. break; } From fbfdaec9777adac9f6b50d9acd23edc24ca2b3e2 Mon Sep 17 00:00:00 2001 From: Marco Magdy Date: Tue, 14 Feb 2023 13:01:15 -0800 Subject: [PATCH 02/10] Fix clang-tidy benign warnings (#185) --- .clang-tidy | 3 ++- ci/codebuild/format-check.sh | 5 +++++ include/aws/lambda-runtime/runtime.h | 3 +-- src/runtime.cpp | 9 +++++++-- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/.clang-tidy b/.clang-tidy index 7d343ea..d42139e 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,6 +1,7 @@ --- Checks: -'clang-diagnostic-*,clang-analyzer-*,performance-*,readability-*,modernize-*,bugprone-*,misc-*,-modernize-use-trailing-return-type' +'clang-diagnostic-*,clang-analyzer-*,performance-*,readability-*,modernize-*,bugprone-*,misc-*, +-modernize-use-trailing-return-type,-bugprone-easily-swappable-parameters,-readability-identifier-length' WarningsAsErrors: '*' HeaderFilterRegex: 'include/aws/.*\.h$' FormatStyle: 'none' diff --git a/ci/codebuild/format-check.sh b/ci/codebuild/format-check.sh index 222b784..035bd54 100755 --- a/ci/codebuild/format-check.sh +++ b/ci/codebuild/format-check.sh @@ -13,6 +13,11 @@ FAIL=0 SOURCE_FILES=$(find src include tests -type f -name "*.h" -o -name "*.cpp") for i in $SOURCE_FILES do + if [[ "$i" == *"gtest.h" || "$i" == *"backward.h" ]]; then + continue + fi + + echo "$i\n" if [ $($CLANG_FORMAT -output-replacements-xml $i | grep -c " #include #include +#include #include // for strtoul #include @@ -133,12 +134,16 @@ static size_t read_data(char* buffer, size_t size, size_t nitems, void* userdata } if (unread <= limit) { - std::copy_n(ctx->first.begin() + ctx->second, unread, buffer); + auto from = ctx->first.begin(); + std::advance(from, ctx->second); + std::copy_n(from, unread, buffer); ctx->second += unread; return unread; } - std::copy_n(ctx->first.begin() + ctx->second, limit, buffer); + auto from = ctx->first.begin(); + std::advance(from, ctx->second); + std::copy_n(from, limit, buffer); ctx->second += limit; return limit; } From fa438eba19f3c536cfcce74737f336146767fde8 Mon Sep 17 00:00:00 2001 From: Krzysiek Karbowiak Date: Wed, 15 Feb 2023 09:16:17 +0100 Subject: [PATCH 03/10] Update actions/checkout to v3 (#181) --- .github/workflows/workflow.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 14bb1da..5cadaf0 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -19,7 +19,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install Dependencies run: sudo apt-get update && sudo apt-get install -y clang-tidy libcurl4-openssl-dev @@ -36,7 +36,7 @@ jobs: build-on-arm-too: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: uraimo/run-on-arch-action@v2 with: arch: aarch64 @@ -52,7 +52,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Check Formatting run: ./ci/codebuild/format-check.sh From c09c86e0268ab8965ebd0ebee142c69c655a3207 Mon Sep 17 00:00:00 2001 From: Krzysiek Karbowiak Date: Mon, 27 Feb 2023 05:45:06 +0100 Subject: [PATCH 04/10] Add building and packaging a demo project to CI and revert #136 (#183) * Add demo project * Add build-demo CI job * Revert "Simplified method for picking out shared libraries from system package query result (#136)" This reverts commit 5fb60b9d93c685e15d036889eb992dabe296d0bc. --------- Co-authored-by: Bryan Moffatt Co-authored-by: Bryan Moffatt --- .github/workflows/workflow.yml | 22 ++++++++++++++++++++++ examples/demo/CMakeLists.txt | 11 +++++++++++ examples/demo/main.cpp | 20 ++++++++++++++++++++ packaging/packager | 17 ++++++++++++----- 4 files changed, 65 insertions(+), 5 deletions(-) create mode 100644 examples/demo/CMakeLists.txt create mode 100644 examples/demo/main.cpp diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 5cadaf0..526b38a 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -46,6 +46,28 @@ jobs: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_CXX_CLANG_TIDY=clang-tidy cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} + build-demo: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Install Dependencies + run: sudo apt-get update && sudo apt-get install -y clang-tidy libcurl4-openssl-dev + + - name: Build and install lambda runtime + run: | + mkdir build && cd build + cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=~/lambda-install + make + make install + + - name: Build and package demo project + run: | + cd examples/demo + mkdir build && cd build + cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=~/lambda-install + make + make aws-lambda-package-demo format: diff --git a/examples/demo/CMakeLists.txt b/examples/demo/CMakeLists.txt new file mode 100644 index 0000000..06aad51 --- /dev/null +++ b/examples/demo/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION 3.9) +set(CMAKE_CXX_STANDARD 11) +project(demo LANGUAGES CXX) +find_package(aws-lambda-runtime) +add_executable(${PROJECT_NAME} "main.cpp") +target_link_libraries(${PROJECT_NAME} PRIVATE AWS::aws-lambda-runtime) +target_compile_features(${PROJECT_NAME} PRIVATE "cxx_std_11") +target_compile_options(${PROJECT_NAME} PRIVATE "-Wall" "-Wextra") + +# this line creates a target that packages your binary and zips it up +aws_lambda_package_target(${PROJECT_NAME}) diff --git a/examples/demo/main.cpp b/examples/demo/main.cpp new file mode 100644 index 0000000..358efe0 --- /dev/null +++ b/examples/demo/main.cpp @@ -0,0 +1,20 @@ +#include + +using namespace aws::lambda_runtime; + +static invocation_response my_handler(invocation_request const& req) +{ + if (req.payload.length() > 42) { + return invocation_response::failure("error message here"/*error_message*/, + "error type here" /*error_type*/); + } + + return invocation_response::success("json payload here" /*payload*/, + "application/json" /*MIME type*/); +} + +int main() +{ + run_handler(my_handler); + return 0; +} diff --git a/packaging/packager b/packaging/packager index 4e8759e..0c4e749 100755 --- a/packaging/packager +++ b/packaging/packager @@ -56,7 +56,7 @@ if ! type zip > /dev/null 2>&1; then exit 1 fi -function find_so_files() { +function pluck_so_files() { sed -E '/\.so$|\.so\.[0-9]+$/!d' } @@ -64,7 +64,7 @@ function package_libc_alpine() { # -F matches a fixed string rather than a regex (grep that comes with busybox doesn't know --fixed-strings) if grep -F "Alpine Linux" < /etc/os-release > /dev/null; then if type apk > /dev/null 2>&1; then - apk info --contents musl 2>/dev/null | find_so_files | sed 's/^/\//' + apk info --contents musl 2>/dev/null | pluck_so_files | sed 's/^/\//' fi fi } @@ -72,20 +72,27 @@ function package_libc_alpine() { function package_libc_pacman() { if grep --extended-regexp "Arch Linux|Manjaro Linux" < /etc/os-release > /dev/null 2>&1; then if type pacman > /dev/null 2>&1; then - pacman --query --list --quiet glibc | find_so_files + pacman --query --list --quiet glibc | pluck_so_files fi fi } function package_libc_dpkg() { if type dpkg-query > /dev/null 2>&1; then - dpkg-query --listfiles libc6:$(dpkg --print-architecture) | find_so_files + architecture=$(dpkg --print-architecture) + if [[ $(dpkg-query --listfiles libc6:$architecture | wc -l) -gt 0 ]]; then + dpkg-query --listfiles libc6:$architecture | pluck_so_files + fi fi } function package_libc_rpm() { + arch=$(uname -m) + if type rpm > /dev/null 2>&1; then - rpm --query --list glibc.$(uname -m) | find_so_files + if [[ $(rpm --query --list glibc.$arch | wc -l) -gt 1 ]]; then + rpm --query --list glibc.$arch | pluck_so_files + fi fi } From f0ad0623682cd9bf9bc9ae2e362cb5a00b28e59a Mon Sep 17 00:00:00 2001 From: Mart Haarman Date: Fri, 24 Mar 2023 22:29:03 +0100 Subject: [PATCH 05/10] Update main.cpp (#178) Co-authored-by: Bryan Moffatt --- examples/s3/main.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/s3/main.cpp b/examples/s3/main.cpp index a389121..892560c 100644 --- a/examples/s3/main.cpp +++ b/examples/s3/main.cpp @@ -73,8 +73,7 @@ int main() config.region = Aws::Environment::GetEnv("AWS_REGION"); config.caFile = "/etc/pki/tls/certs/ca-bundle.crt"; - auto credentialsProvider = Aws::MakeShared(TAG); - S3::S3Client client(credentialsProvider, config); + S3::S3Client client(config); auto handler_fn = [&client](aws::lambda_runtime::invocation_request const& req) { return my_handler(req, client); }; From e08ca6e065877b0ab4eb0e1e43e21c3a3c5f274a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C8=98tefan=20Toma?= <34220105+Stefan9283@users.noreply.github.com> Date: Mon, 23 Oct 2023 20:46:26 +0300 Subject: [PATCH 06/10] Making libbacktrace optional (#189) * Making libbacktrace optional --------- Co-authored-by: Stefan Toma --- CMakeLists.txt | 39 +++++++++++++++++++++++---------------- src/backward.cpp | 6 +++++- src/backward.h | 6 ++++++ 3 files changed, 34 insertions(+), 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 14ee99f..09e226f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,8 +47,29 @@ endif() target_include_directories(${PROJECT_NAME} PRIVATE ${CURL_INCLUDE_DIRS}) -find_package(Backtrace REQUIRED) -target_link_libraries(${PROJECT_NAME} PRIVATE ${Backtrace_LIBRARIES}) +find_package(Backtrace QUIET) +if (${Backtrace_FOUND}) + target_link_libraries(${PROJECT_NAME} PRIVATE ${Backtrace_LIBRARIES}) + + find_library(DW_LIB NAMES dw) + if (NOT DW_LIB STREQUAL DW_LIB-NOTFOUND) + message("-- Enhanced stack-traces are enabled via libdw: ${DW_LIB}") + target_compile_definitions(${PROJECT_NAME} PRIVATE "BACKWARD_HAS_DW=1") + target_link_libraries(${PROJECT_NAME} PUBLIC "${DW_LIB}") + else() + find_library(BFD_LIB NAMES bfd) + if (NOT BFD_LIB STREQUAL BFD_LIB-NOTFOUND) + message("-- Enhanced stack-traces are enabled via libbfd: ${BFD_LIB}") + target_compile_definitions(${PROJECT_NAME} PRIVATE "BACKWARD_HAS_BFD=1") + target_link_libraries(${PROJECT_NAME} PRIVATE "${BFD_LIB}") + endif() + endif() + +else() + message("-- libbacktrace was not installed. Stacktracing will be disabled") + add_definitions(-Dno_backtrace) +endif() + target_compile_options(${PROJECT_NAME} PRIVATE "-fno-exceptions" @@ -61,20 +82,6 @@ target_compile_options(${PROJECT_NAME} PRIVATE "-Wconversion" "-Wno-sign-conversion") -find_library(DW_LIB NAMES dw) -if (NOT DW_LIB STREQUAL DW_LIB-NOTFOUND) - message("-- Enhanced stack-traces are enabled via libdw: ${DW_LIB}") - target_compile_definitions(${PROJECT_NAME} PRIVATE "BACKWARD_HAS_DW=1") - target_link_libraries(${PROJECT_NAME} PUBLIC "${DW_LIB}") -else() - find_library(BFD_LIB NAMES bfd) - if (NOT BFD_LIB STREQUAL BFD_LIB-NOTFOUND) - message("-- Enhanced stack-traces are enabled via libbfd: ${BFD_LIB}") - target_compile_definitions(${PROJECT_NAME} PRIVATE "BACKWARD_HAS_BFD=1") - target_link_libraries(${PROJECT_NAME} PRIVATE "${BFD_LIB}") - endif() -endif() - if (LOG_VERBOSITY) target_compile_definitions(${PROJECT_NAME} PRIVATE "AWS_LAMBDA_LOG=${LOG_VERBOSITY}") elseif(CMAKE_BUILD_TYPE STREQUAL Debug) diff --git a/src/backward.cpp b/src/backward.cpp index cc64abd..8649fd5 100644 --- a/src/backward.cpp +++ b/src/backward.cpp @@ -23,10 +23,14 @@ // - g++/clang++ -lbfd ... // #define BACKWARD_HAS_BFD 1 -#include "backward.h" +#ifndef no_backtrace + +# include "backward.h" namespace backward { backward::SignalHandling sh; } // namespace backward + +#endif diff --git a/src/backward.h b/src/backward.h index c421378..832c452 100644 --- a/src/backward.h +++ b/src/backward.h @@ -28,6 +28,10 @@ # error "It's not going to compile without a C++ compiler..." #endif +#ifdef no_backtrace +# pragma message "Disabling stacktracing" +#else + #if defined(BACKWARD_CXX11) #elif defined(BACKWARD_CXX98) #else @@ -4539,4 +4543,6 @@ class SignalHandling { } // namespace backward +#endif /* no_backtrace */ + #endif /* H_GUARD */ From 934d2547fd573ece89ccbdaad2161a7e4d46fd1e Mon Sep 17 00:00:00 2001 From: Marco Magdy Date: Thu, 16 Nov 2023 09:31:17 -0800 Subject: [PATCH 07/10] Use the Lambda executable as the bootstrap when glibc is not required (#191) * Use the Lambda executable as the bootstrap when glibc is not required * Fix integration tests --------- Co-authored-by: Marco Magdy --- packaging/packager | 13 ++----------- tests/resources/lambda_function.cpp | 9 +++------ 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/packaging/packager b/packaging/packager index 0c4e749..c050696 100755 --- a/packaging/packager +++ b/packaging/packager @@ -171,20 +171,11 @@ exec \$LAMBDA_TASK_ROOT/lib/$PKG_LD --library-path \$LAMBDA_TASK_ROOT/lib \$LAMB EOF ) -bootstrap_script_no_libc=$(cat < "$PKG_DIR/bootstrap" else - echo -e "$bootstrap_script_no_libc" > "$PKG_DIR/bootstrap" + cp "$PKG_BIN_PATH" "$PKG_DIR/bootstrap" fi chmod +x "$PKG_DIR/bootstrap" # some shenanigans to create the right layout in the zip file without extraneous directories diff --git a/tests/resources/lambda_function.cpp b/tests/resources/lambda_function.cpp index b0228d3..bf12fc0 100644 --- a/tests/resources/lambda_function.cpp +++ b/tests/resources/lambda_function.cpp @@ -41,12 +41,9 @@ int main(int argc, char* argv[]) handlers.emplace("binary_response", binary_response); handlers.emplace("crash_backtrace", crash_backtrace); - if (argc < 2) { - aws::logging::log_error("lambda_fun", "Missing handler argument. Exiting."); - return -1; - } - - auto it = handlers.find(argv[1]); + // Read the handler from the environment variable + const char* handler_name = std::getenv("_HANDLER"); + auto it = handlers.find(handler_name == nullptr ? "" : handler_name); if (it == handlers.end()) { aws::logging::log_error("lambda_fun", "Handler %s not found. Exiting.", argv[1]); return -2; From 074d122b34da828fca25a5050a9935dfe85c6c80 Mon Sep 17 00:00:00 2001 From: Christian Ulbrich Date: Tue, 29 Apr 2025 12:52:35 +0200 Subject: [PATCH 08/10] Bugfix/fix minor documentation issues (#203) * Fix docs for current AWS CLI and current AWS Lambda runtimes * provided has to be either provided.al2023 or provided.al2 * AWS CLI2 has changed the param format * add docs about building on arm64 * minor docs update * use proper JSON in example * add hint on how to update example Lambda --- README.md | 18 +++++++++++++----- examples/demo/main.cpp | 2 +- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 74e60af..f702470 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,7 @@ static invocation_response my_handler(invocation_request const& req) "error type here" /*error_type*/); } - return invocation_response::success("json payload here" /*payload*/, + return invocation_response::success("{\"message:\":\"I fail if body length is bigger than 42!\"}" /*payload*/, "application/json" /*MIME type*/); } @@ -130,13 +130,19 @@ And finally, create the Lambda function: ``` $ aws lambda create-function --function-name demo \ --role \ ---runtime provided --timeout 15 --memory-size 128 \ +--runtime provided.al2023 --timeout 15 --memory-size 128 \ --handler demo --zip-file fileb://demo.zip ``` +> **N.B.** If you are building on `arm64`, you have to explicitly add the param `--architectures arm64`, so that you are setting up the proper architecture on AWS to run your supplied Lambda function. And to invoke the function: ```bash -$ aws lambda invoke --function-name demo --payload '{"answer":42}' output.txt +$ aws lambda invoke --function-name demo --cli-binary-format raw-in-base64-out --payload '{"answer":42}' output.txt +``` + +You can update your supplied function: +```bash +$ aws lambda update-function-code --function-name demo --zip-file fileb://demo.zip ``` ## Using the C++ SDK for AWS with this runtime @@ -150,7 +156,7 @@ Any *fully* compliant C++11 compiler targeting GNU/Linux x86-64 should work. Ple - Use Clang v3.3 or above ## Packaging, ABI, GNU C Library, Oh My! -Lambda runs your code on some version of Amazon Linux. It would be a less than ideal customer experience if you are forced to build your application on that platform and that platform only. +Lambda runs your code on some version of Amazon Linux. It would be a less than ideal customer experience if you are forced to build your application on that platform and that platform only. However, the freedom to build on any linux distro brings a challenge. The GNU C Library ABI. There is no guarantee the platform used to build the Lambda function has the same GLIBC version as the one used by AWS Lambda. In fact, you might not even be using GNU's implementation. For example you could build a C++ Lambda function using musl libc. @@ -196,10 +202,12 @@ curl_easy_setopt(curl_handle, CURLOPT_CAINFO, "/etc/pki/tls/certs/ca-bundle.crt" ```bash $ aws lambda create-function --function-name demo \ --role \ - --runtime provided --timeout 15 --memory-size 128 \ + --runtime provided.al2023 --timeout 15 --memory-size 128 \ --handler demo --code "S3Bucket=mys3bucket,S3Key=demo.zip" ``` +> **N.B.** See hint above if you are building on `arm64`. + 1. **My code is crashing, how can I debug it?** - Starting with [v0.2.0](https://github.com/awslabs/aws-lambda-cpp/releases/tag/v0.2.0) you should see a stack-trace of the crash site in the logs (which are typically stored in CloudWatch). diff --git a/examples/demo/main.cpp b/examples/demo/main.cpp index 358efe0..5381311 100644 --- a/examples/demo/main.cpp +++ b/examples/demo/main.cpp @@ -9,7 +9,7 @@ static invocation_response my_handler(invocation_request const& req) "error type here" /*error_type*/); } - return invocation_response::success("json payload here" /*payload*/, + return invocation_response::success("{\"message:\":\"I fail if body length is bigger than 42!\"}" /*payload*/, "application/json" /*MIME type*/); } From 0e99247d90dbec53f68c4f7ffafab321e582e1d4 Mon Sep 17 00:00:00 2001 From: koki watanabe <56009584+math-hiyoko@users.noreply.github.com> Date: Tue, 29 Apr 2025 21:33:10 +0900 Subject: [PATCH 09/10] delete extra space (#198) --- src/runtime.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/runtime.cpp b/src/runtime.cpp index 2ae91e2..1013a19 100644 --- a/src/runtime.cpp +++ b/src/runtime.cpp @@ -527,7 +527,7 @@ invocation_response invocation_response::failure(std::string const& error_messag r.m_success = false; r.m_content_type = "application/json"; r.m_payload = R"({"errorMessage":")" + json_escape(error_message) + R"(","errorType":")" + json_escape(error_type) + - R"(", "stackTrace":[]})"; + R"(","stackTrace":[]})"; return r; } From d89a26aa818cf4c61fa442287e2ed548ae63c42f Mon Sep 17 00:00:00 2001 From: Maxime David Date: Wed, 30 Apr 2025 13:35:38 +0100 Subject: [PATCH 10/10] feat: add unit tests in ci (#201) --- .clang-tidy | 1 + .github/workflows/workflow.yml | 35 ++++----------- README.md | 17 ++++++++ tests/CMakeLists.txt | 53 ++++++++++++++++++----- tests/{ => integration}/main.cpp | 2 +- tests/{ => integration}/runtime_tests.cpp | 2 +- tests/{ => integration}/version_tests.cpp | 2 +- tests/unit/no_op_test.cpp | 6 +++ 8 files changed, 78 insertions(+), 40 deletions(-) rename tests/{ => integration}/main.cpp (97%) rename tests/{ => integration}/runtime_tests.cpp (99%) rename tests/{ => integration}/version_tests.cpp (93%) create mode 100644 tests/unit/no_op_test.cpp diff --git a/.clang-tidy b/.clang-tidy index d42139e..616d471 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -4,6 +4,7 @@ Checks: -modernize-use-trailing-return-type,-bugprone-easily-swappable-parameters,-readability-identifier-length' WarningsAsErrors: '*' HeaderFilterRegex: 'include/aws/.*\.h$' +ExcludeHeaderFilter: 'build/_deps/gtest-src.*' FormatStyle: 'none' CheckOptions: - key: modernize-pass-by-value.ValuesOnly diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 526b38a..7da0628 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -12,39 +12,24 @@ env: jobs: build: - # The CMake configure and build commands are platform agnostic and should work equally - # well on Windows or Mac. You can convert this to a matrix build if you need - # cross-platform coverage. - # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix - runs-on: ubuntu-latest + strategy: + matrix: + arch: [ubuntu-latest, ubuntu-24.04-arm] + runs-on: ${{ matrix.arch }} steps: - uses: actions/checkout@v3 - - name: Install Dependencies run: sudo apt-get update && sudo apt-get install -y clang-tidy libcurl4-openssl-dev - name: Configure CMake - # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. - # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type - run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_CXX_CLANG_TIDY=clang-tidy + run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_CXX_CLANG_TIDY=clang-tidy -DENABLE_TESTS=ON - name: Build It - # Build your program with the given configuration run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} - build-on-arm-too: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: uraimo/run-on-arch-action@v2 - with: - arch: aarch64 - distro: ubuntu20.04 - run: | - apt-get update && apt-get install -y cmake g++ clang-tidy libcurl4-openssl-dev - cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_CXX_CLANG_TIDY=clang-tidy - cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} + - name: Test It + run: cd build && make && ctest build-demo: runs-on: ubuntu-latest @@ -68,15 +53,11 @@ jobs: cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=~/lambda-install make make aws-lambda-package-demo - - + format: runs-on: ubuntu-latest - steps: - uses: actions/checkout@v3 - name: Check Formatting run: ./ci/codebuild/format-check.sh - - diff --git a/README.md b/README.md index f702470..0f58b28 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,23 @@ $ cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=~/lambda-install $ make && make install ``` +### Running Unit Tests Locally + +To run the unit tests locally, follow these steps to build: + +```bash +$ cd aws-lambda-cpp +$ mkdir build +$ cd build +$ cmake .. -DCMAKE_BUILD_TYPE=Debug -DENABLE_TESTS=ON +$ make +``` + +Run unit tests: +```bash +$ ctest +``` + To consume this library in a project that is also using CMake, you would do: ```cmake diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 06bf89a..7406096 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,17 +1,50 @@ +cmake_minimum_required(VERSION 3.11) project(aws-lambda-runtime-tests LANGUAGES CXX) -find_package(AWSSDK COMPONENTS lambda iam) +if(DEFINED ENV{GITHUB_ACTIONS}) + # Fetch Google Test for unit tests + include(FetchContent) + FetchContent_Declare(gtest + URL https://github.com/google/googletest/archive/v1.12.0.tar.gz + DOWNLOAD_EXTRACT_TIMESTAMP TRUE + ) + # Configure build of googletest + set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) + set(BUILD_GMOCK OFF CACHE BOOL "" FORCE) + set(INSTALL_GTEST OFF) + FetchContent_MakeAvailable(gtest) -add_executable(${PROJECT_NAME} - main.cpp - runtime_tests.cpp - version_tests.cpp - gtest/gtest-all.cc) + add_executable(unit_tests + unit/no_op_test.cpp) + target_link_libraries(unit_tests PRIVATE gtest_main aws-lambda-runtime) -target_link_libraries(${PROJECT_NAME} PRIVATE ${AWSSDK_LINK_LIBRARIES} aws-lambda-runtime) + # Register unit tests + include(GoogleTest) + gtest_discover_tests(unit_tests + PROPERTIES + LABELS "unit" + DISCOVERY_TIMEOUT 10) +else() + message(STATUS "Unit tests skipped: Not in GitHub Actions environment") +endif() -include(GoogleTest) -gtest_discover_tests(${PROJECT_NAME} EXTRA_ARGS "--aws_prefix=${TEST_RESOURCE_PREFIX}") # requires CMake 3.10 or later -add_subdirectory(resources) +find_package(AWSSDK COMPONENTS lambda iam QUIET) + +if(AWSSDK_FOUND) + add_executable(${PROJECT_NAME} + integration/main.cpp + integration/runtime_tests.cpp + integration/version_tests.cpp + gtest/gtest-all.cc) + + target_link_libraries(${PROJECT_NAME} PRIVATE ${AWSSDK_LINK_LIBRARIES} aws-lambda-runtime) + + include(GoogleTest) + gtest_discover_tests(${PROJECT_NAME} EXTRA_ARGS "--aws_prefix=${TEST_RESOURCE_PREFIX}") + + add_subdirectory(resources) +else() + message(STATUS "Integration tests skipped: AWS SDK not found or not in GitHub Actions environment") +endif() diff --git a/tests/main.cpp b/tests/integration/main.cpp similarity index 97% rename from tests/main.cpp rename to tests/integration/main.cpp index d7700e8..2a112d3 100644 --- a/tests/main.cpp +++ b/tests/integration/main.cpp @@ -1,6 +1,6 @@ #include #include -#include "gtest/gtest.h" +#include "../gtest/gtest.h" std::function()> get_console_logger_factory() { diff --git a/tests/runtime_tests.cpp b/tests/integration/runtime_tests.cpp similarity index 99% rename from tests/runtime_tests.cpp rename to tests/integration/runtime_tests.cpp index f118dab..843f815 100644 --- a/tests/runtime_tests.cpp +++ b/tests/integration/runtime_tests.cpp @@ -13,7 +13,7 @@ #include #include #include -#include "gtest/gtest.h" +#include "../gtest/gtest.h" #include #include #include diff --git a/tests/version_tests.cpp b/tests/integration/version_tests.cpp similarity index 93% rename from tests/version_tests.cpp rename to tests/integration/version_tests.cpp index 070b6dd..a0f546e 100644 --- a/tests/version_tests.cpp +++ b/tests/integration/version_tests.cpp @@ -1,5 +1,5 @@ #include -#include "gtest/gtest.h" +#include "../gtest/gtest.h" using namespace aws::lambda_runtime; diff --git a/tests/unit/no_op_test.cpp b/tests/unit/no_op_test.cpp new file mode 100644 index 0000000..c9a3b7d --- /dev/null +++ b/tests/unit/no_op_test.cpp @@ -0,0 +1,6 @@ +#include + +TEST(noop, dummy_test) +{ + ASSERT_EQ(0, 0); +}