diff --git a/.github/workflows/unittests.yml b/.github/workflows/unittests.yml index 6e60a4c..9a4478c 100644 --- a/.github/workflows/unittests.yml +++ b/.github/workflows/unittests.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Install dependencies - run: sudo /usr/bin/env DEBIAN_FRONTEND=noninteractive apt-get install libgtest-dev cmake git libsodium-dev + run: sudo /usr/bin/env DEBIAN_FRONTEND=noninteractive apt-get install cmake git libsodium-dev - name: Get sources run: git clone --depth=1 --no-single-branch https://github.com/Stephen-Seo/UDPConnection.git UDPC && cd UDPC && git checkout $GITHUB_REF_NAME - name: Build sources diff --git a/CMakeLists.txt b/CMakeLists.txt index 589d533..4ed0671 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,21 +59,18 @@ else() endif() if(CMAKE_BUILD_TYPE MATCHES "Debug") - - find_package(GTest QUIET) - if(GTEST_FOUND) - set(UDPC_UnitTest_SOURCES - src/CXX11_shared_spin_lock.cpp - src/test/UDPC_UnitTest.cpp - src/test/TestTSLQueue.cpp - src/test/TestUDPC.cpp - src/test/TestSharedSpinLock.cpp - ) - add_executable(UnitTest ${UDPC_UnitTest_SOURCES}) - target_compile_features(UnitTest PUBLIC cxx_std_11) - target_link_libraries(UnitTest PUBLIC UDPC ${GTEST_BOTH_LIBRARIES}) - target_include_directories(UnitTest PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src) - endif() + set(UDPC_UnitTest_SOURCES + src/CXX11_shared_spin_lock.cpp + src/test/UDPC_UnitTest.cpp + src/test/TestTSLQueue.cpp + src/test/TestUDPC.cpp + src/test/TestSharedSpinLock.cpp + ) + add_executable(UnitTest ${UDPC_UnitTest_SOURCES}) + target_compile_features(UnitTest PUBLIC cxx_std_11) + target_link_libraries(UnitTest PUBLIC UDPC) + target_include_directories(UnitTest PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src) + target_compile_options(UnitTest PRIVATE "-Wno-sign-compare") set(UDPC_NetworkTest_SOURCES src/test/UDPC_NetworkTest.c) diff --git a/README.md b/README.md index 021fb33..1edc35d 100644 --- a/README.md +++ b/README.md @@ -73,8 +73,7 @@ and is also an example of using the library in a C program. NetworkTest only builds when CMAKE\_BUILD\_TYPE is Debug (default). -UnitTest only builds in Debug mode and if GTest (a unit testing framework) is -available. +UnitTest only builds in Debug mode. # Links https://github.com/Stephen-Seo/UDPConnection diff --git a/src/test/TestSharedSpinLock.cpp b/src/test/TestSharedSpinLock.cpp index dda0e4e..b352975 100644 --- a/src/test/TestSharedSpinLock.cpp +++ b/src/test/TestSharedSpinLock.cpp @@ -1,18 +1,18 @@ -#include - #include "CXX11_shared_spin_lock.hpp" +#include "test_helpers.h" +#include "test_headers.h" -TEST(CXX11_shared_spin_lock, simple) { +void TEST_CXX11_shared_spin_lock() { UDPC::SharedSpinLock::Ptr spinLockPtr = UDPC::SharedSpinLock::newInstance(); auto readLock = spinLockPtr->spin_read_lock(); - EXPECT_TRUE(readLock.isValid()); - EXPECT_TRUE(spinLockPtr->spin_read_lock().isValid()); - EXPECT_FALSE(spinLockPtr->try_spin_write_lock().isValid()); + CHECK_TRUE(readLock.isValid()); + CHECK_TRUE(spinLockPtr->spin_read_lock().isValid()); + CHECK_FALSE(spinLockPtr->try_spin_write_lock().isValid()); auto writeLock = spinLockPtr->trade_read_for_write_lock(readLock); - EXPECT_TRUE(writeLock.isValid()); - EXPECT_FALSE(readLock.isValid()); - EXPECT_FALSE(spinLockPtr->try_spin_read_lock().isValid()); - EXPECT_FALSE(spinLockPtr->try_spin_write_lock().isValid()); + CHECK_TRUE(writeLock.isValid()); + CHECK_FALSE(readLock.isValid()); + CHECK_FALSE(spinLockPtr->try_spin_read_lock().isValid()); + CHECK_FALSE(spinLockPtr->try_spin_write_lock().isValid()); } diff --git a/src/test/TestTSLQueue.cpp b/src/test/TestTSLQueue.cpp index b46de73..f8ed089 100644 --- a/src/test/TestTSLQueue.cpp +++ b/src/test/TestTSLQueue.cpp @@ -1,276 +1,286 @@ -#include +#include "test_helpers.h" +#include "test_headers.h" #include #include #include "TSLQueue.hpp" -TEST(TSLQueue, PushTopPopSize) { - TSLQueue q; - - EXPECT_FALSE(q.top()); - - for(int i = 0; i < 10; ++i) { - EXPECT_EQ(i, q.size()); - q.push(i); - } - - for(int i = 0; i < 10; ++i) { - auto v = q.top(); - ASSERT_TRUE(v); - EXPECT_EQ(*v, i); - EXPECT_EQ(10 - i, q.size()); - EXPECT_TRUE(q.pop()); - } - EXPECT_EQ(q.size(), 0); - - EXPECT_FALSE(q.pop()); -} - -TEST(TSLQueue, PushNB_TopNB_TopAndPop_Size) { - TSLQueue q; - - for(int i = 0; i < 10; ++i) { - EXPECT_EQ(q.size(), i); - EXPECT_TRUE(q.push_nb(i)); - } - - for(int i = 0; i < 10; ++i) { - auto v = q.top_nb(); - ASSERT_TRUE(v); - EXPECT_EQ(*v, i); - EXPECT_EQ(q.size(), 10 - i); - v = q.top_and_pop(); - ASSERT_TRUE(v); - EXPECT_EQ(*v, i); - } - +void TEST_TSLQueue() { + // PushTopPopSize { - auto v = q.top_nb(); - ASSERT_FALSE(v); + TSLQueue q; + + CHECK_FALSE(q.top()); + + for(int i = 0; i < 10; ++i) { + CHECK_EQ(i, q.size()); + q.push(i); + } + + for(int i = 0; i < 10; ++i) { + auto v = q.top(); + ASSERT_TRUE(v); + CHECK_EQ(*v, i); + CHECK_EQ(10 - i, q.size()); + CHECK_TRUE(q.pop()); + } + CHECK_EQ(q.size(), 0); + + CHECK_FALSE(q.pop()); } + + // PushNB_TopNB_TopAndPop_Size { - auto v = q.top_and_pop(); - ASSERT_FALSE(v); - } - EXPECT_EQ(q.size(), 0); -} + TSLQueue q; -TEST(TSLQueue, Push_TopAndPopAndEmpty_Size) { - TSLQueue q; + for(int i = 0; i < 10; ++i) { + CHECK_EQ(q.size(), i); + CHECK_TRUE(q.push_nb(i)); + } - for(int i = 0; i < 10; ++i) { - EXPECT_EQ(q.size(), i); - q.push(i); + for(int i = 0; i < 10; ++i) { + auto v = q.top_nb(); + ASSERT_TRUE(v); + CHECK_EQ(*v, i); + CHECK_EQ(q.size(), 10 - i); + v = q.top_and_pop(); + ASSERT_TRUE(v); + CHECK_EQ(*v, i); + } + + { + auto v = q.top_nb(); + ASSERT_FALSE(v); + } + { + auto v = q.top_and_pop(); + ASSERT_FALSE(v); + } + CHECK_EQ(q.size(), 0); } - bool isEmpty; - for(int i = 0; i < 10; ++i) { - EXPECT_EQ(q.size(), 10 - i); - auto v = q.top_and_pop_and_empty(&isEmpty); - ASSERT_TRUE(v); - EXPECT_EQ(*v, i); - EXPECT_EQ(i == 9, isEmpty); - } - EXPECT_EQ(q.size(), 0); -} - -TEST(TSLQueue, PushClearEmptySize) { - TSLQueue q; - - for(int i = 0; i < 10; ++i) { - EXPECT_EQ(q.size(), i); - q.push(i); - } - EXPECT_EQ(q.size(), 10); - - EXPECT_FALSE(q.empty()); - q.clear(); - EXPECT_TRUE(q.empty()); - EXPECT_EQ(q.size(), 0); -} - -TEST(TSLQueue, Concurrent) { - TSLQueue q; - - const auto add_fn = [] (TSLQueue *q, int i) -> void { - q->push(i); - }; - - std::future futures[100]; - for(int i = 0; i < 100; ++i) { - futures[i] = std::async(std::launch::async, add_fn, &q, i); - } - for(int i = 0; i < 100; ++i) { - futures[i].wait(); - } - - EXPECT_FALSE(q.empty()); - for(int i = 0; i < 100; ++i) { - EXPECT_EQ(q.size(), 100 - i); - auto v = q.top_and_pop(); - ASSERT_TRUE(v); - EXPECT_GE(*v, 0); - EXPECT_LE(*v, 100); - EXPECT_EQ(i == 99, q.empty()); - } - EXPECT_EQ(q.size(), 0); -} - -TEST(TSLQueue, Iterator) { - TSLQueue q; - - for(int i = 0; i < 10; ++i) { - q.push(i); - } - EXPECT_EQ(q.size(), 10); - + // Push_TopAndPopAndEmpty_Size { - // iteration - auto iter = q.begin(); + TSLQueue q; + + for(int i = 0; i < 10; ++i) { + CHECK_EQ(q.size(), i); + q.push(i); + } + + bool isEmpty; + for(int i = 0; i < 10; ++i) { + CHECK_EQ(q.size(), 10 - i); + auto v = q.top_and_pop_and_empty(&isEmpty); + ASSERT_TRUE(v); + CHECK_EQ(*v, i); + CHECK_EQ(i == 9, isEmpty); + } + CHECK_EQ(q.size(), 0); + } + + // PushClearEmptySize + { + TSLQueue q; + + for(int i = 0; i < 10; ++i) { + CHECK_EQ(q.size(), i); + q.push(i); + } + CHECK_EQ(q.size(), 10); + + CHECK_FALSE(q.empty()); + q.clear(); + CHECK_TRUE(q.empty()); + CHECK_EQ(q.size(), 0); + } + + // Concurrent + { + TSLQueue q; + + const auto add_fn = [] (TSLQueue *q, int i) -> void { + q->push(i); + }; + + std::future futures[100]; + for(int i = 0; i < 100; ++i) { + futures[i] = std::async(std::launch::async, add_fn, &q, i); + } + for(int i = 0; i < 100; ++i) { + futures[i].wait(); + } + + CHECK_FALSE(q.empty()); + for(int i = 0; i < 100; ++i) { + CHECK_EQ(q.size(), 100 - i); + auto v = q.top_and_pop(); + ASSERT_TRUE(v); + CHECK_GE(*v, 0); + CHECK_LE(*v, 100); + CHECK_EQ(i == 99, q.empty()); + } + CHECK_EQ(q.size(), 0); + } + + // Iterator + { + TSLQueue q; + + for(int i = 0; i < 10; ++i) { + q.push(i); + } + CHECK_EQ(q.size(), 10); + + { + // iteration + auto iter = q.begin(); + int i = 0; + auto op = iter.current(); + while(op) { + CHECK_EQ(*op, i++); + if(i < 10) { + CHECK_TRUE(iter.next()); + } else { + CHECK_FALSE(iter.next()); + } + op = iter.current(); + } + + // test that lock is held by iterator + CHECK_FALSE(q.push_nb(10)); + op = q.top_nb(); + // Getting top and iterator both hold read locks so this should be true. + CHECK_TRUE(op); + + // backwards iteration + CHECK_TRUE(iter.prev()); + op = iter.current(); + while(op) { + CHECK_EQ(*op, --i); + if(i > 0) { + CHECK_TRUE(iter.prev()); + } else { + CHECK_FALSE(iter.prev()); + } + op = iter.current(); + } + } + + { + // iter remove + auto iter = q.begin(); + CHECK_TRUE(iter.next()); + CHECK_TRUE(iter.next()); + CHECK_TRUE(iter.next()); + CHECK_TRUE(iter.remove()); + + auto op = iter.current(); + CHECK_TRUE(op); + CHECK_EQ(*op, 4); + + CHECK_TRUE(iter.prev()); + op = iter.current(); + CHECK_TRUE(op); + CHECK_EQ(*op, 2); + + // second iterator + auto iter2 = q.begin(); + + // Still should be able to get top. + CHECK_TRUE(iter2.current()); + + // Shouldn't be able to remove if 2 iterators exist. + CHECK_FALSE(iter2.try_remove()); + + // This will never return since the first iterator has a "read" lock. + //CHECK_FALSE(iter2.remove()); + + // Still should be able to get top. + CHECK_TRUE(iter2.current()); + } + CHECK_EQ(q.size(), 9); + + // check that "3" was removed from queue int i = 0; - auto op = iter.current(); - while(op) { - EXPECT_EQ(*op, i++); - if(i < 10) { - EXPECT_TRUE(iter.next()); - } else { - EXPECT_FALSE(iter.next()); + std::unique_ptr op; + while(!q.empty()) { + op = q.top(); + CHECK_TRUE(op); + CHECK_EQ(i++, *op); + if(i == 3) { + ++i; } - op = iter.current(); + CHECK_TRUE(q.pop()); } - // test that lock is held by iterator - EXPECT_FALSE(q.push_nb(10)); - op = q.top_nb(); - // Getting top and iterator both hold read locks so this should be true. - EXPECT_TRUE(op); + // remove from start + q.push(0); + q.push(1); + q.push(2); + q.push(3); + CHECK_EQ(q.size(), 4); + { + auto iter = q.begin(); + CHECK_TRUE(iter.remove()); + } + CHECK_EQ(q.size(), 3); + i = 1; + while(!q.empty()) { + op = q.top(); + CHECK_TRUE(op); + CHECK_EQ(i++, *op); + CHECK_TRUE(q.pop()); + } - // backwards iteration - EXPECT_TRUE(iter.prev()); - op = iter.current(); - while(op) { - EXPECT_EQ(*op, --i); - if(i > 0) { - EXPECT_TRUE(iter.prev()); - } else { - EXPECT_FALSE(iter.prev()); + // remove from end + q.push(0); + q.push(1); + q.push(2); + q.push(3); + CHECK_EQ(q.size(), 4); + { + auto iter = q.begin(); + while(true) { + CHECK_TRUE(iter.next()); + op = iter.current(); + CHECK_TRUE(op); + if(*op == 3) { + CHECK_FALSE(iter.remove()); + break; + } } - op = iter.current(); } - } - - { - // iter remove - auto iter = q.begin(); - EXPECT_TRUE(iter.next()); - EXPECT_TRUE(iter.next()); - EXPECT_TRUE(iter.next()); - EXPECT_TRUE(iter.remove()); - - auto op = iter.current(); - EXPECT_TRUE(op); - EXPECT_EQ(*op, 4); - - EXPECT_TRUE(iter.prev()); - op = iter.current(); - EXPECT_TRUE(op); - EXPECT_EQ(*op, 2); - - // second iterator - auto iter2 = q.begin(); - - // Still should be able to get top. - EXPECT_TRUE(iter2.current()); - - // Shouldn't be able to remove if 2 iterators exist. - EXPECT_FALSE(iter2.try_remove()); - - // This will never return since the first iterator has a "read" lock. - //EXPECT_FALSE(iter2.remove()); - - // Still should be able to get top. - EXPECT_TRUE(iter2.current()); - } - EXPECT_EQ(q.size(), 9); - - // check that "3" was removed from queue - int i = 0; - std::unique_ptr op; - while(!q.empty()) { - op = q.top(); - EXPECT_TRUE(op); - EXPECT_EQ(i++, *op); - if(i == 3) { - ++i; - } - EXPECT_TRUE(q.pop()); - } - - // remove from start - q.push(0); - q.push(1); - q.push(2); - q.push(3); - EXPECT_EQ(q.size(), 4); - { - auto iter = q.begin(); - EXPECT_TRUE(iter.remove()); - } - EXPECT_EQ(q.size(), 3); - i = 1; - while(!q.empty()) { - op = q.top(); - EXPECT_TRUE(op); - EXPECT_EQ(i++, *op); - EXPECT_TRUE(q.pop()); - } - - // remove from end - q.push(0); - q.push(1); - q.push(2); - q.push(3); - EXPECT_EQ(q.size(), 4); - { - auto iter = q.begin(); - while(true) { - EXPECT_TRUE(iter.next()); - op = iter.current(); - EXPECT_TRUE(op); - if(*op == 3) { - EXPECT_FALSE(iter.remove()); - break; + CHECK_EQ(q.size(), 3); + i = 0; + while(!q.empty()) { + op = q.top(); + CHECK_TRUE(op); + CHECK_EQ(i++, *op); + CHECK_TRUE(q.pop()); + if(i == 3) { + CHECK_TRUE(q.empty()); } } } - EXPECT_EQ(q.size(), 3); - i = 0; - while(!q.empty()) { - op = q.top(); - EXPECT_TRUE(op); - EXPECT_EQ(i++, *op); - EXPECT_TRUE(q.pop()); - if(i == 3) { - EXPECT_TRUE(q.empty()); - } + + // TempToNew + { + TSLQueue q; + + q.push(1234); + q.push(5678); + + auto getValue = [] (TSLQueue *q) -> int { + auto uptr = q->top_and_pop(); + return *uptr; + }; + int value; + + value = getValue(&q); + CHECK_EQ(1234, value); + value = getValue(&q); + CHECK_EQ(5678, value); } } - -TEST(TSLQueue, TempToNew) { - TSLQueue q; - - q.push(1234); - q.push(5678); - - auto getValue = [] (TSLQueue *q) -> int { - auto uptr = q->top_and_pop(); - return *uptr; - }; - int value; - - value = getValue(&q); - EXPECT_EQ(1234, value); - value = getValue(&q); - EXPECT_EQ(5678, value); -} diff --git a/src/test/TestUDPC.cpp b/src/test/TestUDPC.cpp index a63cde5..0bb3dfa 100644 --- a/src/test/TestUDPC.cpp +++ b/src/test/TestUDPC.cpp @@ -1,464 +1,478 @@ -#include +#include "test_headers.h" +#include "test_helpers.h" #include #include +#include #include #include #include #include -TEST(UDPC, atostr) { - UDPC::Context context(false); +void TEST_UDPC() { + // atostr + { + UDPC::Context context(false); - UDPC_ConnectionId conId; - const char* resultBuf; + UDPC_ConnectionId conId; + const char* resultBuf; - for(unsigned int i = 0; i < 16; ++i) { - conId.addr.s6_addr[i] = (i % 3 == 0 ? 0xFF : (i % 3 == 1 ? 0x12 : 0x56)); - } - resultBuf = UDPC_atostr((UDPC_HContext)&context, conId.addr); - EXPECT_STREQ(resultBuf, "ff12:56ff:1256:ff12:56ff:1256:ff12:56ff"); - - for(unsigned int i = 0; i < 8; ++i) { - conId.addr.s6_addr[i] = 0; - } - resultBuf = UDPC_atostr((UDPC_HContext)&context, conId.addr); - EXPECT_STREQ(resultBuf, "::56ff:1256:ff12:56ff"); - - conId.addr.s6_addr[0] = 1; - conId.addr.s6_addr[1] = 2; - resultBuf = UDPC_atostr((UDPC_HContext)&context, conId.addr); - EXPECT_STREQ(resultBuf, "102::56ff:1256:ff12:56ff"); - - conId.addr.s6_addr[14] = 0; - conId.addr.s6_addr[15] = 0; - resultBuf = UDPC_atostr((UDPC_HContext)&context, conId.addr); - EXPECT_STREQ(resultBuf, "102::56ff:1256:ff12:0"); - - for(unsigned int i = 0; i < 15; ++i) { - conId.addr.s6_addr[i] = 0; - } - conId.addr.s6_addr[15] = 1; - - resultBuf = UDPC_atostr((UDPC_HContext)&context, conId.addr); - EXPECT_STREQ(resultBuf, "::1"); - - conId.addr.s6_addr[15] = 0; - - resultBuf = UDPC_atostr((UDPC_HContext)&context, conId.addr); - EXPECT_STREQ(resultBuf, "::"); - - conId.addr = { - 0xAE, 0x0, 0x12, 1, - 0x10, 0x45, 0x2, 0x13, - 0, 0, 0, 0, - 0, 0, 0, 0 - }; - resultBuf = UDPC_atostr((UDPC_HContext)&context, conId.addr); - EXPECT_STREQ(resultBuf, "ae00:1201:1045:213::"); -} - -TEST(UDPC, atostr_concurrent) { - UDPC::Context context(false); - - const char* results[64] = { - "::1111:1", - "::1111:2", - "::1111:3", - "::1111:4", - "::1111:5", - "::1111:6", - "::1111:7", - "::1111:8", - "::1111:9", - "::1111:a", - "::1111:b", - "::1111:c", - "::1111:d", - "::1111:e", - "::1111:f", - "::1111:10", - "::1111:11", - "::1111:12", - "::1111:13", - "::1111:14", - "::1111:15", - "::1111:16", - "::1111:17", - "::1111:18", - "::1111:19", - "::1111:1a", - "::1111:1b", - "::1111:1c", - "::1111:1d", - "::1111:1e", - "::1111:1f", - "::1111:20", - "::1111:21", - "::1111:22", - "::1111:23", - "::1111:24", - "::1111:25", - "::1111:26", - "::1111:27", - "::1111:28", - "::1111:29", - "::1111:2a", - "::1111:2b", - "::1111:2c", - "::1111:2d", - "::1111:2e", - "::1111:2f", - "::1111:30", - "::1111:31", - "::1111:32", - "::1111:33", - "::1111:34", - "::1111:35", - "::1111:36", - "::1111:37", - "::1111:38", - "::1111:39", - "::1111:3a", - "::1111:3b", - "::1111:3c", - "::1111:3d", - "::1111:3e", - "::1111:3f", - "::1111:40" - }; - - std::future futures[32]; - const char* ptrs[32]; - for(unsigned int i = 0; i < 2; ++i) { - for(unsigned int j = 0; j < 32; ++j) { - futures[j] = std::async(std::launch::async, [] (unsigned int id, const char** ptr, UDPC::Context* c) { - UDPC_ConnectionId conId = { - {0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0x11, 0x11, 0x0, (unsigned char)(id + 1)}, - 0, - 0 - }; - ptr[id] = UDPC_atostr((UDPC_HContext)c, conId.addr); - }, j, ptrs, &context); + for(unsigned int i = 0; i < 16; ++i) { + conId.addr.s6_addr[i] = (i % 3 == 0 ? 0xFF : (i % 3 == 1 ? 0x12 : 0x56)); } - for(unsigned int j = 0; j < 32; ++j) { - ASSERT_TRUE(futures[j].valid()); - futures[j].wait(); + resultBuf = UDPC_atostr((UDPC_HContext)&context, conId.addr); + CHECK_STREQ(resultBuf, "ff12:56ff:1256:ff12:56ff:1256:ff12:56ff"); + + for(unsigned int i = 0; i < 8; ++i) { + conId.addr.s6_addr[i] = 0; } - for(unsigned int j = 0; j < 32; ++j) { - EXPECT_STREQ(ptrs[j], results[j]); + resultBuf = UDPC_atostr((UDPC_HContext)&context, conId.addr); + CHECK_STREQ(resultBuf, "::56ff:1256:ff12:56ff"); + + conId.addr.s6_addr[0] = 1; + conId.addr.s6_addr[1] = 2; + resultBuf = UDPC_atostr((UDPC_HContext)&context, conId.addr); + CHECK_STREQ(resultBuf, "102::56ff:1256:ff12:56ff"); + + conId.addr.s6_addr[14] = 0; + conId.addr.s6_addr[15] = 0; + resultBuf = UDPC_atostr((UDPC_HContext)&context, conId.addr); + CHECK_STREQ(resultBuf, "102::56ff:1256:ff12:0"); + + for(unsigned int i = 0; i < 15; ++i) { + conId.addr.s6_addr[i] = 0; + } + conId.addr.s6_addr[15] = 1; + + resultBuf = UDPC_atostr((UDPC_HContext)&context, conId.addr); + CHECK_STREQ(resultBuf, "::1"); + + conId.addr.s6_addr[15] = 0; + + resultBuf = UDPC_atostr((UDPC_HContext)&context, conId.addr); + CHECK_STREQ(resultBuf, "::"); + + conId.addr = { + 0xAE, 0x0, 0x12, 1, + 0x10, 0x45, 0x2, 0x13, + 0, 0, 0, 0, + 0, 0, 0, 0 + }; + resultBuf = UDPC_atostr((UDPC_HContext)&context, conId.addr); + CHECK_STREQ(resultBuf, "ae00:1201:1045:213::"); + } + + // atostr_concurrent + { + UDPC::Context context(false); + + const char* results[64] = { + "::1111:1", + "::1111:2", + "::1111:3", + "::1111:4", + "::1111:5", + "::1111:6", + "::1111:7", + "::1111:8", + "::1111:9", + "::1111:a", + "::1111:b", + "::1111:c", + "::1111:d", + "::1111:e", + "::1111:f", + "::1111:10", + "::1111:11", + "::1111:12", + "::1111:13", + "::1111:14", + "::1111:15", + "::1111:16", + "::1111:17", + "::1111:18", + "::1111:19", + "::1111:1a", + "::1111:1b", + "::1111:1c", + "::1111:1d", + "::1111:1e", + "::1111:1f", + "::1111:20", + "::1111:21", + "::1111:22", + "::1111:23", + "::1111:24", + "::1111:25", + "::1111:26", + "::1111:27", + "::1111:28", + "::1111:29", + "::1111:2a", + "::1111:2b", + "::1111:2c", + "::1111:2d", + "::1111:2e", + "::1111:2f", + "::1111:30", + "::1111:31", + "::1111:32", + "::1111:33", + "::1111:34", + "::1111:35", + "::1111:36", + "::1111:37", + "::1111:38", + "::1111:39", + "::1111:3a", + "::1111:3b", + "::1111:3c", + "::1111:3d", + "::1111:3e", + "::1111:3f", + "::1111:40" + }; + + std::future futures[32]; + const char* ptrs[32]; + for(unsigned int i = 0; i < 2; ++i) { + for(unsigned int j = 0; j < 32; ++j) { + futures[j] = std::async(std::launch::async, [] (unsigned int id, const char** ptr, UDPC::Context* c) { + UDPC_ConnectionId conId = { + {0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0x11, 0x11, 0x0, (unsigned char)(id + 1)}, + 0, + 0 + }; + ptr[id] = UDPC_atostr((UDPC_HContext)c, conId.addr); + }, j, ptrs, &context); + } + for(unsigned int j = 0; j < 32; ++j) { + ASSERT_TRUE(futures[j].valid()); + futures[j].wait(); + } + for(unsigned int j = 0; j < 32; ++j) { + CHECK_STREQ(ptrs[j], results[j]); + } } } -} -TEST(UDPC, atostr_unsafe) { - const char* results[64] = { - "::1111:1", - "::1111:2", - "::1111:3", - "::1111:4", - "::1111:5", - "::1111:6", - "::1111:7", - "::1111:8", - "::1111:9", - "::1111:a", - "::1111:b", - "::1111:c", - "::1111:d", - "::1111:e", - "::1111:f", - "::1111:10", - "::1111:11", - "::1111:12", - "::1111:13", - "::1111:14", - "::1111:15", - "::1111:16", - "::1111:17", - "::1111:18", - "::1111:19", - "::1111:1a", - "::1111:1b", - "::1111:1c", - "::1111:1d", - "::1111:1e", - "::1111:1f", - "::1111:20", - "::1111:21", - "::1111:22", - "::1111:23", - "::1111:24", - "::1111:25", - "::1111:26", - "::1111:27", - "::1111:28", - "::1111:29", - "::1111:2a", - "::1111:2b", - "::1111:2c", - "::1111:2d", - "::1111:2e", - "::1111:2f", - "::1111:30", - "::1111:31", - "::1111:32", - "::1111:33", - "::1111:34", - "::1111:35", - "::1111:36", - "::1111:37", - "::1111:38", - "::1111:39", - "::1111:3a", - "::1111:3b", - "::1111:3c", - "::1111:3d", - "::1111:3e", - "::1111:3f", - "::1111:40" - }; - std::future futures[32]; - const char* ptrs[32]; - for(unsigned int i = 0; i < 2; ++i) { - for(unsigned int j = 0; j < 32; ++j) { - futures[j] = std::async(std::launch::async, [] (unsigned int id, const char** ptr) { - UDPC_ConnectionId conId = { - {0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0x11, 0x11, 0x0, (unsigned char)(id + 1)}, - 0, - 0 - }; - ptr[id] = UDPC_atostr_unsafe(conId.addr); - }, j, ptrs); - } - for(unsigned int j = 0; j < 32; ++j) { - ASSERT_TRUE(futures[j].valid()); - futures[j].wait(); - } - for(unsigned int j = 0; j < 32; ++j) { - EXPECT_STREQ(ptrs[j], results[j]); - UDPC_atostr_unsafe_free_ptr(ptrs + j); - UDPC_atostr_unsafe_free_ptr(ptrs + j); + // atostr_unsafe + { + const char* results[64] = { + "::1111:1", + "::1111:2", + "::1111:3", + "::1111:4", + "::1111:5", + "::1111:6", + "::1111:7", + "::1111:8", + "::1111:9", + "::1111:a", + "::1111:b", + "::1111:c", + "::1111:d", + "::1111:e", + "::1111:f", + "::1111:10", + "::1111:11", + "::1111:12", + "::1111:13", + "::1111:14", + "::1111:15", + "::1111:16", + "::1111:17", + "::1111:18", + "::1111:19", + "::1111:1a", + "::1111:1b", + "::1111:1c", + "::1111:1d", + "::1111:1e", + "::1111:1f", + "::1111:20", + "::1111:21", + "::1111:22", + "::1111:23", + "::1111:24", + "::1111:25", + "::1111:26", + "::1111:27", + "::1111:28", + "::1111:29", + "::1111:2a", + "::1111:2b", + "::1111:2c", + "::1111:2d", + "::1111:2e", + "::1111:2f", + "::1111:30", + "::1111:31", + "::1111:32", + "::1111:33", + "::1111:34", + "::1111:35", + "::1111:36", + "::1111:37", + "::1111:38", + "::1111:39", + "::1111:3a", + "::1111:3b", + "::1111:3c", + "::1111:3d", + "::1111:3e", + "::1111:3f", + "::1111:40" + }; + std::future futures[32]; + const char* ptrs[32]; + for(unsigned int i = 0; i < 2; ++i) { + for(unsigned int j = 0; j < 32; ++j) { + futures[j] = std::async(std::launch::async, [] (unsigned int id, const char** ptr) { + UDPC_ConnectionId conId = { + {0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0x11, 0x11, 0x0, (unsigned char)(id + 1)}, + 0, + 0 + }; + ptr[id] = UDPC_atostr_unsafe(conId.addr); + }, j, ptrs); + } + for(unsigned int j = 0; j < 32; ++j) { + ASSERT_TRUE(futures[j].valid()); + futures[j].wait(); + } + for(unsigned int j = 0; j < 32; ++j) { + CHECK_STREQ(ptrs[j], results[j]); + UDPC_atostr_unsafe_free_ptr(ptrs + j); + UDPC_atostr_unsafe_free_ptr(ptrs + j); + } } } -} -TEST(UDPC, strtoa) { - struct in6_addr addr; + // strtoa + { + struct in6_addr addr; - for(unsigned int i = 0; i < 16; ++i) { - addr.s6_addr[i] = 0; - } - addr.s6_addr[15] = 1; + for(unsigned int i = 0; i < 16; ++i) { + addr.s6_addr[i] = 0; + } + addr.s6_addr[15] = 1; - EXPECT_EQ(UDPC_strtoa("::1"), addr); + CHECK_EQ(UDPC_strtoa("::1"), addr); - // check invalid - EXPECT_EQ(UDPC_strtoa("1:1::1:1::1"), addr); - EXPECT_EQ(UDPC_strtoa("derpadoodle"), addr); + // check invalid + CHECK_EQ(UDPC_strtoa("1:1::1:1::1"), addr); + CHECK_EQ(UDPC_strtoa("derpadoodle"), addr); - addr = { - 0xF0, 0xF, 0x0, 0x1, - 0x56, 0x78, 0x9A, 0xBC, - 0xDE, 0xFF, 0x1, 0x2, - 0x3, 0x4, 0x5, 0x6 - }; - EXPECT_EQ(UDPC_strtoa("F00F:1:5678:9abc:deff:102:304:506"), addr); + addr = { + 0xF0, 0xF, 0x0, 0x1, + 0x56, 0x78, 0x9A, 0xBC, + 0xDE, 0xFF, 0x1, 0x2, + 0x3, 0x4, 0x5, 0x6 + }; + CHECK_EQ(UDPC_strtoa("F00F:1:5678:9abc:deff:102:304:506"), addr); - addr = { - 0x0, 0xFF, 0x1, 0x0, - 0x0, 0x1, 0x10, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x12, 0x34, 0xab, 0xcd - }; - EXPECT_EQ(UDPC_strtoa("ff:100:1:1000::1234:abcd"), addr); + addr = { + 0x0, 0xFF, 0x1, 0x0, + 0x0, 0x1, 0x10, 0x0, + 0x0, 0x0, 0x0, 0x0, + 0x12, 0x34, 0xab, 0xcd + }; + CHECK_EQ(UDPC_strtoa("ff:100:1:1000::1234:abcd"), addr); - addr = { - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xFF, 0xFF, - 0x7F, 0x0, 0x0, 0x1 - }; - EXPECT_EQ(UDPC_strtoa("127.0.0.1"), addr); + addr = { + 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xFF, 0xFF, + 0x7F, 0x0, 0x0, 0x1 + }; + CHECK_EQ(UDPC_strtoa("127.0.0.1"), addr); - addr = { - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xFF, 0xFF, - 0xA, 0x1, 0x2, 0x3 - }; - EXPECT_EQ(UDPC_strtoa("10.1.2.3"), addr); -} - -TEST(UDPC, create_id_easy) { - UDPC_ConnectionId conId; - - // not link local - conId = UDPC_create_id_easy("::FFFF:7F00:1", 301); - for(unsigned int i = 0; i < 10; ++i) { - EXPECT_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[i], 0); - } - EXPECT_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[10], 0xFF); - EXPECT_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[11], 0xFF); - EXPECT_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[12], 0x7F); - EXPECT_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[13], 0); - EXPECT_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[14], 0); - EXPECT_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[15], 0x1); - - EXPECT_EQ(conId.scope_id, 0); - EXPECT_EQ(conId.port, 301); - - // link local - conId = UDPC_create_id_easy("fe80::1234:5678:9%3", 123); - EXPECT_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[0], 0xFE); - EXPECT_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[1], 0x80); - for(unsigned int i = 2; i < 10; ++i) { - EXPECT_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[i], 0); - } - EXPECT_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[10], 0x12); - EXPECT_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[11], 0x34); - EXPECT_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[12], 0x56); - EXPECT_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[13], 0x78); - EXPECT_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[14], 0); - EXPECT_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[15], 0x9); - - EXPECT_EQ(conId.scope_id, 3); - EXPECT_EQ(conId.port, 123); -} - -TEST(UDPC, ConnectionIdBits) { - UDPC_ConnectionId id = UDPC_create_id({0}, 0); - for(unsigned int i = 0; i < sizeof(UDPC_ConnectionId); ++i) { - EXPECT_EQ(((char*)&id)[i], 0); + addr = { + 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xFF, 0xFF, + 0xA, 0x1, 0x2, 0x3 + }; + CHECK_EQ(UDPC_strtoa("10.1.2.3"), addr); } - id = UDPC_create_id_full({0}, 0, 0); - for(unsigned int i = 0; i < sizeof(UDPC_ConnectionId); ++i) { - EXPECT_EQ(((char*)&id)[i], 0); + // create_id_easy + { + UDPC_ConnectionId conId; + + // not link local + conId = UDPC_create_id_easy("::FFFF:7F00:1", 301); + for(unsigned int i = 0; i < 10; ++i) { + CHECK_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[i], 0); + } + CHECK_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[10], 0xFF); + CHECK_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[11], 0xFF); + CHECK_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[12], 0x7F); + CHECK_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[13], 0); + CHECK_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[14], 0); + CHECK_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[15], 0x1); + + CHECK_EQ(conId.scope_id, 0); + CHECK_EQ(conId.port, 301); + + // link local + conId = UDPC_create_id_easy("fe80::1234:5678:9%3", 123); + CHECK_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[0], 0xFE); + CHECK_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[1], 0x80); + for(unsigned int i = 2; i < 10; ++i) { + CHECK_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[i], 0); + } + CHECK_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[10], 0x12); + CHECK_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[11], 0x34); + CHECK_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[12], 0x56); + CHECK_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[13], 0x78); + CHECK_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[14], 0); + CHECK_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[15], 0x9); + + CHECK_EQ(conId.scope_id, 3); + CHECK_EQ(conId.port, 123); } - id = UDPC_create_id_anyaddr(0); - for(unsigned int i = 0; i < sizeof(UDPC_ConnectionId); ++i) { - EXPECT_EQ(((char*)&id)[i], 0); + // ConnectionIdBits + { + UDPC_ConnectionId id = UDPC_create_id({0}, 0); + for(unsigned int i = 0; i < sizeof(UDPC_ConnectionId); ++i) { + CHECK_EQ(((char*)&id)[i], 0); + } + + id = UDPC_create_id_full({0}, 0, 0); + for(unsigned int i = 0; i < sizeof(UDPC_ConnectionId); ++i) { + CHECK_EQ(((char*)&id)[i], 0); + } + + id = UDPC_create_id_anyaddr(0); + for(unsigned int i = 0; i < sizeof(UDPC_ConnectionId); ++i) { + CHECK_EQ(((char*)&id)[i], 0); + } + + id = UDPC_create_id_easy("::", 0); + for(unsigned int i = 0; i < sizeof(UDPC_ConnectionId); ++i) { + CHECK_EQ(((char*)&id)[i], 0); + } } - id = UDPC_create_id_easy("::", 0); - for(unsigned int i = 0; i < sizeof(UDPC_ConnectionId); ++i) { - EXPECT_EQ(((char*)&id)[i], 0); - } -} + // NetworkOrderEndianness + { + if(UDPC_is_big_endian() != 0) { + puts("Is big-endian"); + uint16_t s = 0x0102; + s = UDPC_no16i(s); + CHECK_EQ(s, 0x0102); -TEST(UDPC, NetworkOrderEndianness) { - if(UDPC_is_big_endian() != 0) { - puts("Is big-endian"); - uint16_t s = 0x0102; - s = UDPC_no16i(s); - EXPECT_EQ(s, 0x0102); + uint32_t l = 0x01020304; + l = UDPC_no32i(l); + CHECK_EQ(l, 0x01020304); - uint32_t l = 0x01020304; - l = UDPC_no32i(l); - EXPECT_EQ(l, 0x01020304); + uint64_t ll = 0x0102030405060708; + ll = UDPC_no64i(ll); + CHECK_EQ(ll, 0x0102030405060708); - uint64_t ll = 0x0102030405060708; - ll = UDPC_no64i(ll); - EXPECT_EQ(ll, 0x0102030405060708); + l = 0x40208040; + float *f = reinterpret_cast(&l); + *f = UDPC_no32f(*f); + CHECK_EQ(l, 0x40208040); - l = 0x40208040; - float *f = reinterpret_cast(&l); - *f = UDPC_no32f(*f); - EXPECT_EQ(l, 0x40208040); - - ll = 0x4000001010008040; - double *d = reinterpret_cast(&ll); - *d = UDPC_no64f(*d); - EXPECT_EQ(ll, 0x4000001010008040); - } else { - puts("Is NOT big-endian"); - uint16_t s = 0x0102; - s = UDPC_no16i(s); - EXPECT_EQ(s, 0x0201); - s = UDPC_no16i(s); - EXPECT_EQ(s, 0x0102); - - uint32_t l = 0x01020304; - l = UDPC_no32i(l); - EXPECT_EQ(l, 0x04030201); - l = UDPC_no32i(l); - EXPECT_EQ(l, 0x01020304); - - uint64_t ll = 0x0102030405060708; - ll = UDPC_no64i(ll); - EXPECT_EQ(ll, 0x0807060504030201); - ll = UDPC_no64i(ll); - EXPECT_EQ(ll, 0x0102030405060708); - - l = 0x40208040; - float *f = reinterpret_cast(&l); - *f = UDPC_no32f(*f); - EXPECT_EQ(l, 0x40802040); - *f = UDPC_no32f(*f); - EXPECT_EQ(l, 0x40208040); - - ll = 0x4000001010008040; - double *d = reinterpret_cast(&ll); - *d = UDPC_no64f(*d); - EXPECT_EQ(ll, 0x4080001010000040); - *d = UDPC_no64f(*d); - EXPECT_EQ(ll, 0x4000001010008040); - } -} - -TEST(UDPC, a4toa6) { - EXPECT_EQ(UDPC_a4toa6(0), in6addr_any); - uint32_t a4 = htonl(0x7F000001); - EXPECT_EQ(UDPC_a4toa6(a4), in6addr_loopback); - - UDPC_IPV6_ADDR_TYPE a6 = UDPC_strtoa("::FFFF:0102:0304"); - a4 = htonl(0x01020304); - EXPECT_EQ(UDPC_a4toa6(a4), a6); -} - -TEST(UDPC, free_packet_ptr) { - UDPC_PacketInfo pinfo; - pinfo.dataSize = 8; - pinfo.data = (char*)std::malloc(pinfo.dataSize); - - UDPC_free_PacketInfo_ptr(&pinfo); - UDPC_free_PacketInfo_ptr(&pinfo); - UDPC_free_PacketInfo_ptr(nullptr); -} - -TEST(UDPC, enableDisableThreadedUpdate_StressTest) { - UDPC_ConnectionId id = UDPC_create_id_anyaddr(0); - UDPC_HContext ctx = UDPC_init(id, 0, 0); - - UDPC_set_logging_type(ctx, UDPC_LoggingType::UDPC_WARNING); - - std::array thread_array; - for (int i = 0; i < 100; ++i) { - if (i % 2 == 0) { - thread_array[i] = std::thread([] (UDPC_HContext ctx) { - UDPC_enable_threaded_update(ctx); - }, ctx); + ll = 0x4000001010008040; + double *d = reinterpret_cast(&ll); + *d = UDPC_no64f(*d); + CHECK_EQ(ll, 0x4000001010008040); } else { - thread_array[i] = std::thread([] (UDPC_HContext ctx) { - UDPC_disable_threaded_update(ctx); - }, ctx); + puts("Is NOT big-endian"); + uint16_t s = 0x0102; + s = UDPC_no16i(s); + CHECK_EQ(s, 0x0201); + s = UDPC_no16i(s); + CHECK_EQ(s, 0x0102); + + uint32_t l = 0x01020304; + l = UDPC_no32i(l); + CHECK_EQ(l, 0x04030201); + l = UDPC_no32i(l); + CHECK_EQ(l, 0x01020304); + + uint64_t ll = 0x0102030405060708; + ll = UDPC_no64i(ll); + CHECK_EQ(ll, 0x0807060504030201); + ll = UDPC_no64i(ll); + CHECK_EQ(ll, 0x0102030405060708); + + l = 0x40208040; + float *f = reinterpret_cast(&l); + *f = UDPC_no32f(*f); + CHECK_EQ(l, 0x40802040); + *f = UDPC_no32f(*f); + CHECK_EQ(l, 0x40208040); + + ll = 0x4000001010008040; + double *d = reinterpret_cast(&ll); + *d = UDPC_no64f(*d); + CHECK_EQ(ll, 0x4080001010000040); + *d = UDPC_no64f(*d); + CHECK_EQ(ll, 0x4000001010008040); } } - thread_array[0].join(); + // a4toa6 + { + CHECK_EQ(UDPC_a4toa6(0), in6addr_any); + uint32_t a4 = htonl(0x7F000001); + CHECK_EQ(UDPC_a4toa6(a4), in6addr_loopback); - UDPC_destroy(ctx); + UDPC_IPV6_ADDR_TYPE a6 = UDPC_strtoa("::FFFF:0102:0304"); + a4 = htonl(0x01020304); + CHECK_EQ(UDPC_a4toa6(a4), a6); + } - for (int i = 1; i < 100; ++i) { - thread_array[i].join(); + // free_packet_ptr + { + UDPC_PacketInfo pinfo; + pinfo.dataSize = 8; + pinfo.data = (char*)std::malloc(pinfo.dataSize); + + UDPC_free_PacketInfo_ptr(&pinfo); + UDPC_free_PacketInfo_ptr(&pinfo); + UDPC_free_PacketInfo_ptr(nullptr); + } + + // enableDisableThreadedUpdate_StressTest + { + UDPC_ConnectionId id = UDPC_create_id_anyaddr(0); + UDPC_HContext ctx = UDPC_init(id, 0, 0); + + UDPC_set_logging_type(ctx, UDPC_LoggingType::UDPC_WARNING); + + std::array thread_array; + for (int i = 0; i < 100; ++i) { + if (i % 2 == 0) { + thread_array[i] = std::thread([] (UDPC_HContext ctx) { + UDPC_enable_threaded_update(ctx); + }, ctx); + } else { + thread_array[i] = std::thread([] (UDPC_HContext ctx) { + UDPC_disable_threaded_update(ctx); + }, ctx); + } + } + + thread_array[0].join(); + + UDPC_destroy(ctx); + + for (int i = 1; i < 100; ++i) { + thread_array[i].join(); + } } } diff --git a/src/test/UDPC_UnitTest.cpp b/src/test/UDPC_UnitTest.cpp index 5ebbc76..b6fba37 100644 --- a/src/test/UDPC_UnitTest.cpp +++ b/src/test/UDPC_UnitTest.cpp @@ -1,6 +1,18 @@ -#include +#include "test_helpers.h" +#include "test_headers.h" -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); +int checks_checked = 0; +int checks_passed = 0; + +#include + +int main() { + TEST_CXX11_shared_spin_lock(); + TEST_TSLQueue(); + TEST_UDPC(); + + std::cout << "checks_checked: " << checks_checked + << "\nchecks_passed: " << checks_passed << std::endl; + + return checks_checked == checks_passed ? 0 : 1; } diff --git a/src/test/test_headers.h b/src/test/test_headers.h new file mode 100644 index 0000000..96db11e --- /dev/null +++ b/src/test/test_headers.h @@ -0,0 +1,10 @@ +#ifndef SEODISPARATE_COM_UDPC_TEST_HEADERS_H_ +#define SEODISPARATE_COM_UDPC_TEST_HEADERS_H_ + +void TEST_CXX11_shared_spin_lock(); + +void TEST_TSLQueue(); + +void TEST_UDPC(); + +#endif diff --git a/src/test/test_helpers.h b/src/test/test_helpers.h new file mode 100644 index 0000000..4f8b31e --- /dev/null +++ b/src/test/test_helpers.h @@ -0,0 +1,108 @@ +#ifndef SEODISPARATE_COM_UDPC_TEST_HELPERS_H_ +#define SEODISPARATE_COM_UDPC_TEST_HELPERS_H_ + +#include +#include + +extern int checks_checked; +extern int checks_passed; + +// Macros for unit testing. + +#define CHECK_TRUE(x) \ + do { \ + ++checks_checked; \ + if (!(x)) { \ + std::cout << "CHECK_TRUE at line " << __LINE__ << " failed: " << #x \ + << '\n'; \ + } else { \ + ++checks_passed; \ + } \ + } while (false); +#define ASSERT_TRUE(x) \ + do { \ + ++checks_checked; \ + if (!(x)) { \ + std::cout << "CHECK_TRUE at line " << __LINE__ << " failed: " << #x \ + << '\n'; \ + return; \ + } else { \ + ++checks_passed; \ + } \ + } while (false); +#define CHECK_FALSE(x) \ + do { \ + ++checks_checked; \ + if (x) { \ + std::cout << "CHECK_FALSE at line " << __LINE__ << " failed: " << #x \ + << '\n'; \ + } else { \ + ++checks_passed; \ + } \ + } while (false); +#define ASSERT_FALSE(x) \ + do { \ + ++checks_checked; \ + if (x) { \ + std::cout << "CHECK_FALSE at line " << __LINE__ << " failed: " << #x \ + << '\n'; \ + return; \ + } else { \ + ++checks_passed; \ + } \ + } while (false); + +#define CHECK_FLOAT(var, value) \ + do { \ + ++checks_checked; \ + if ((var) > (value) - 0.0001F && (var) < (value) + 0.0001F) { \ + ++checks_passed; \ + } else { \ + std::cout << "CHECK_FLOAT at line " << __LINE__ << " failed: " << #var \ + << " != " << #value << '\n'; \ + } \ + } while (false); + +#define CHECK_EQ(var, value) \ + do { \ + ++checks_checked; \ + if ((var) == (value)) { \ + ++checks_passed; \ + } else { \ + std::cout << "CHECK_EQ at line " << __LINE__ << " failed: " << #var \ + << " != " << #value << '\n'; \ + } \ + } while (false); +#define CHECK_GE(var, value) \ + do { \ + ++checks_checked; \ + if ((var) >= (value)) { \ + ++checks_passed; \ + } else { \ + std::cout << "CHECK_GE at line " << __LINE__ << " failed: " << #var \ + << " < " << #value << '\n'; \ + } \ + } while (false); +#define CHECK_LE(var, value) \ + do { \ + ++checks_checked; \ + if ((var) <= (value)) { \ + ++checks_passed; \ + } else { \ + std::cout << "CHECK_LE at line " << __LINE__ << " failed: " << #var \ + << " > " << #value << '\n'; \ + } \ + } while (false); + +#define CHECK_STREQ(str_a, str_b) \ + do { \ + ++checks_checked; \ + if (std::strcmp((str_a), (str_b)) == 0) { \ + ++checks_passed; \ + } else { \ + std::cout << "CHECK_STREQ at line " << __LINE__ << "failed: " << #str_a \ + << " != " << #str_b << '\n'; \ + } \ + } while (false); + +#endif