Browse Source

Add unit tests for the tid allocator (#2519)

Add simple infrastructure to add more unit tests in the future. At the moment tests
are only executed on Linux, but can be extended to other platforms if needed.

Use https://github.com/google/googletest/ as a framework.
Marcin Kolny 2 năm trước cách đây
mục cha
commit
8c2dc1d011

+ 10 - 2
.github/workflows/compilation_on_android_ubuntu.yml

@@ -72,7 +72,7 @@ jobs:
     with:
       os: "ubuntu-22.04"
       arch: "X86"
-  
+
   build_wamrc:
     needs:
       [build_llvm_libraries_on_ubuntu_2204]
@@ -241,6 +241,14 @@ jobs:
           cmake --build . --config Release --parallel 4
         working-directory: product-mini/platforms/${{ matrix.platform }}
 
+      - name: Build and run unit tests
+        run: |
+          mkdir build-unittests && cd build-unittests
+          cmake .. ${{ matrix.make_options_run_mode }} ${{ matrix.make_options_feature }}
+          cmake --build . --config Release --parallel 4
+          ctest
+        working-directory: tests/unit
+
   build_samples_wasm_c_api:
     needs:
       [
@@ -483,7 +491,7 @@ jobs:
           sudo tar -xzf wasi-sdk-*.tar.gz
           sudo mv wasi-sdk-20.0 wasi-sdk
 
-      # It is a temporary solution until new wasi-sdk that includes bug fixes is released 
+      # It is a temporary solution until new wasi-sdk that includes bug fixes is released
       - name: build wasi-libc from source
         if: matrix.test_option == '$WASI_TEST_OPTIONS'
         run: |

+ 10 - 0
core/iwasm/libraries/lib-wasi-threads/tid_allocator.h

@@ -8,8 +8,14 @@
 
 #include "platform_common.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #define TID_ALLOCATOR_INIT_SIZE CLUSTER_MAX_THREAD_NUM
 enum {
+    /* Keep it in sync with
+       https://github.com/WebAssembly/wasi-threads#design-choice-thread-ids */
     TID_MIN = 1,
     TID_MAX = 0x1FFFFFFF
 }; // Reserved TIDs (WASI specification)
@@ -33,4 +39,8 @@ tid_allocator_get_tid(TidAllocator *tid_allocator);
 void
 tid_allocator_release_tid(TidAllocator *tid_allocator, int32 thread_id);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* _TID_ALLOCATOR_H */

+ 6 - 0
core/iwasm/libraries/lib-wasi-threads/unit-test/lib_wasi_threads_unit_tests.cmake

@@ -0,0 +1,6 @@
+# Copyright (C) 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+create_wamr_unit_test(wasi_threads
+    ${CMAKE_CURRENT_LIST_DIR}/test_tid_allocator.cpp
+)

+ 62 - 0
core/iwasm/libraries/lib-wasi-threads/unit-test/test_tid_allocator.cpp

@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2023 Amazon.com Inc. or its affiliates. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#include <gtest/gtest.h>
+
+#include "tid_allocator.h"
+
+#include <stdint.h>
+
+class TidAllocatorTest : public ::testing::Test
+{
+  protected:
+    void SetUp() override { ASSERT_TRUE(tid_allocator_init(&_allocator)); }
+
+    void TearDown() override { tid_allocator_deinit(&_allocator); }
+
+    TidAllocator _allocator;
+};
+
+static bool
+is_tid_valid(int32 tid)
+{
+    /* See: https://github.com/WebAssembly/wasi-threads#design-choice-thread-ids
+     */
+    return tid >= TID_MIN && tid <= TID_MAX;
+}
+
+TEST_F(TidAllocatorTest, BasicTest)
+{
+    int32 tid = tid_allocator_get_tid(&_allocator);
+
+    ASSERT_TRUE(is_tid_valid(tid));
+}
+
+TEST_F(TidAllocatorTest, ShouldFailOnAllocatingMoreThanAllowedThreadIDs)
+{
+    int32 last_tid = 0;
+    for (int32 i = 0; i < TID_MAX + 1; i++) {
+        last_tid = tid_allocator_get_tid(&_allocator);
+        if (last_tid < 0) {
+            break;
+        }
+        ASSERT_TRUE(is_tid_valid(last_tid));
+    }
+
+    ASSERT_LT(last_tid, 0);
+}
+
+TEST_F(TidAllocatorTest, ShouldAllocateMoreThanAllowedTIDsIfOldTIDsAreReleased)
+{
+    int32 last_tid = 0;
+    for (int32 i = 0; i < TID_MAX + 1; i++) {
+        if (last_tid != 0) {
+            tid_allocator_release_tid(&_allocator, last_tid);
+        }
+
+        last_tid = tid_allocator_get_tid(&_allocator);
+        ASSERT_TRUE(is_tid_valid(last_tid));
+    }
+}

+ 51 - 0
tests/unit/CMakeLists.txt

@@ -0,0 +1,51 @@
+# Copyright (C) 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+cmake_minimum_required (VERSION 3.14)
+
+project (wamr_unit_tests)
+
+include (CTest)
+
+if (NOT DEFINED WAMR_BUILD_INTERP)
+  # Enable Interpreter by default
+  set (WAMR_BUILD_INTERP 1)
+endif ()
+
+if (NOT DEFINED WAMR_BUILD_PLATFORM)
+  string (TOLOWER ${CMAKE_HOST_SYSTEM_NAME} WAMR_BUILD_PLATFORM)
+endif ()
+
+set (WAMR_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
+include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
+add_library (vmlib ${WAMR_RUNTIME_LIB_SOURCE})
+
+include (FetchContent)
+FetchContent_Declare (
+    googletest
+    URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip
+)
+# For Windows: Prevent overriding the parent project's compiler/linker settings
+set (gtest_force_shared_crt ON CACHE BOOL "" FORCE)
+FetchContent_MakeAvailable (googletest)
+
+include (GoogleTest)
+
+add_library (wamr_gtest_main main.cpp)
+target_link_libraries (wamr_gtest_main PUBLIC gtest vmlib)
+
+function (create_wamr_unit_test test_name)
+    set (sources ${ARGN})
+    add_executable (${test_name} ${sources})
+    target_link_libraries (
+        ${test_name}
+        wamr_gtest_main
+        vmlib
+        ${LLVM_AVAILABLE_LIBS}
+    )
+    gtest_discover_tests (${test_name})
+    endfunction ()
+
+if (WAMR_BUILD_LIB_WASI_THREADS EQUAL 1)
+    include (${IWASM_DIR}/libraries/lib-wasi-threads/unit-test/lib_wasi_threads_unit_tests.cmake)
+endif ()

+ 21 - 0
tests/unit/main.cpp

@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2023 Amazon.com Inc. or its affiliates. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+#include <gtest/gtest.h>
+#include "wasm_runtime_common.h"
+
+int
+main(int argc, char **argv)
+{
+    ::testing::InitGoogleTest(&argc, argv);
+
+    if (!wasm_runtime_init()) {
+        return -1;
+    }
+
+    int ret = RUN_ALL_TESTS();
+    wasm_runtime_destroy();
+
+    return ret;
+}