Rework unit-tests to not use GTest
This commit is contained in:
parent
510156bc58
commit
c6b13de9f8
9 changed files with 852 additions and 702 deletions
2
.github/workflows/unittests.yml
vendored
2
.github/workflows/unittests.yml
vendored
|
@ -9,7 +9,7 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Install dependencies
|
- 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
|
- 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
|
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
|
- name: Build sources
|
||||||
|
|
|
@ -59,21 +59,18 @@ else()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CMAKE_BUILD_TYPE MATCHES "Debug")
|
if(CMAKE_BUILD_TYPE MATCHES "Debug")
|
||||||
|
set(UDPC_UnitTest_SOURCES
|
||||||
find_package(GTest QUIET)
|
src/CXX11_shared_spin_lock.cpp
|
||||||
if(GTEST_FOUND)
|
src/test/UDPC_UnitTest.cpp
|
||||||
set(UDPC_UnitTest_SOURCES
|
src/test/TestTSLQueue.cpp
|
||||||
src/CXX11_shared_spin_lock.cpp
|
src/test/TestUDPC.cpp
|
||||||
src/test/UDPC_UnitTest.cpp
|
src/test/TestSharedSpinLock.cpp
|
||||||
src/test/TestTSLQueue.cpp
|
)
|
||||||
src/test/TestUDPC.cpp
|
add_executable(UnitTest ${UDPC_UnitTest_SOURCES})
|
||||||
src/test/TestSharedSpinLock.cpp
|
target_compile_features(UnitTest PUBLIC cxx_std_11)
|
||||||
)
|
target_link_libraries(UnitTest PUBLIC UDPC)
|
||||||
add_executable(UnitTest ${UDPC_UnitTest_SOURCES})
|
target_include_directories(UnitTest PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src)
|
||||||
target_compile_features(UnitTest PUBLIC cxx_std_11)
|
target_compile_options(UnitTest PRIVATE "-Wno-sign-compare")
|
||||||
target_link_libraries(UnitTest PUBLIC UDPC ${GTEST_BOTH_LIBRARIES})
|
|
||||||
target_include_directories(UnitTest PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(UDPC_NetworkTest_SOURCES
|
set(UDPC_NetworkTest_SOURCES
|
||||||
src/test/UDPC_NetworkTest.c)
|
src/test/UDPC_NetworkTest.c)
|
||||||
|
|
|
@ -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).
|
NetworkTest only builds when CMAKE\_BUILD\_TYPE is Debug (default).
|
||||||
|
|
||||||
UnitTest only builds in Debug mode and if GTest (a unit testing framework) is
|
UnitTest only builds in Debug mode.
|
||||||
available.
|
|
||||||
|
|
||||||
# Links
|
# Links
|
||||||
https://github.com/Stephen-Seo/UDPConnection
|
https://github.com/Stephen-Seo/UDPConnection
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
#include <gtest/gtest.h>
|
|
||||||
|
|
||||||
#include "CXX11_shared_spin_lock.hpp"
|
#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();
|
UDPC::SharedSpinLock::Ptr spinLockPtr = UDPC::SharedSpinLock::newInstance();
|
||||||
|
|
||||||
auto readLock = spinLockPtr->spin_read_lock();
|
auto readLock = spinLockPtr->spin_read_lock();
|
||||||
EXPECT_TRUE(readLock.isValid());
|
CHECK_TRUE(readLock.isValid());
|
||||||
EXPECT_TRUE(spinLockPtr->spin_read_lock().isValid());
|
CHECK_TRUE(spinLockPtr->spin_read_lock().isValid());
|
||||||
EXPECT_FALSE(spinLockPtr->try_spin_write_lock().isValid());
|
CHECK_FALSE(spinLockPtr->try_spin_write_lock().isValid());
|
||||||
|
|
||||||
auto writeLock = spinLockPtr->trade_read_for_write_lock(readLock);
|
auto writeLock = spinLockPtr->trade_read_for_write_lock(readLock);
|
||||||
EXPECT_TRUE(writeLock.isValid());
|
CHECK_TRUE(writeLock.isValid());
|
||||||
EXPECT_FALSE(readLock.isValid());
|
CHECK_FALSE(readLock.isValid());
|
||||||
EXPECT_FALSE(spinLockPtr->try_spin_read_lock().isValid());
|
CHECK_FALSE(spinLockPtr->try_spin_read_lock().isValid());
|
||||||
EXPECT_FALSE(spinLockPtr->try_spin_write_lock().isValid());
|
CHECK_FALSE(spinLockPtr->try_spin_write_lock().isValid());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,276 +1,286 @@
|
||||||
#include <gtest/gtest.h>
|
#include "test_helpers.h"
|
||||||
|
#include "test_headers.h"
|
||||||
|
|
||||||
#include <future>
|
#include <future>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
#include "TSLQueue.hpp"
|
#include "TSLQueue.hpp"
|
||||||
|
|
||||||
TEST(TSLQueue, PushTopPopSize) {
|
void TEST_TSLQueue() {
|
||||||
TSLQueue<int> q;
|
// PushTopPopSize
|
||||||
|
|
||||||
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<int> 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
auto v = q.top_nb();
|
TSLQueue<int> q;
|
||||||
ASSERT_FALSE(v);
|
|
||||||
|
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();
|
TSLQueue<int> q;
|
||||||
ASSERT_FALSE(v);
|
|
||||||
}
|
|
||||||
EXPECT_EQ(q.size(), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(TSLQueue, Push_TopAndPopAndEmpty_Size) {
|
for(int i = 0; i < 10; ++i) {
|
||||||
TSLQueue<int> q;
|
CHECK_EQ(q.size(), i);
|
||||||
|
CHECK_TRUE(q.push_nb(i));
|
||||||
|
}
|
||||||
|
|
||||||
for(int i = 0; i < 10; ++i) {
|
for(int i = 0; i < 10; ++i) {
|
||||||
EXPECT_EQ(q.size(), i);
|
auto v = q.top_nb();
|
||||||
q.push(i);
|
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;
|
// Push_TopAndPopAndEmpty_Size
|
||||||
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<int> 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<int> q;
|
|
||||||
|
|
||||||
const auto add_fn = [] (TSLQueue<int> *q, int i) -> void {
|
|
||||||
q->push(i);
|
|
||||||
};
|
|
||||||
|
|
||||||
std::future<void> 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<int> q;
|
|
||||||
|
|
||||||
for(int i = 0; i < 10; ++i) {
|
|
||||||
q.push(i);
|
|
||||||
}
|
|
||||||
EXPECT_EQ(q.size(), 10);
|
|
||||||
|
|
||||||
{
|
{
|
||||||
// iteration
|
TSLQueue<int> q;
|
||||||
auto iter = q.begin();
|
|
||||||
|
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<int> 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<int> q;
|
||||||
|
|
||||||
|
const auto add_fn = [] (TSLQueue<int> *q, int i) -> void {
|
||||||
|
q->push(i);
|
||||||
|
};
|
||||||
|
|
||||||
|
std::future<void> 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<int> 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;
|
int i = 0;
|
||||||
auto op = iter.current();
|
std::unique_ptr<int> op;
|
||||||
while(op) {
|
while(!q.empty()) {
|
||||||
EXPECT_EQ(*op, i++);
|
op = q.top();
|
||||||
if(i < 10) {
|
CHECK_TRUE(op);
|
||||||
EXPECT_TRUE(iter.next());
|
CHECK_EQ(i++, *op);
|
||||||
} else {
|
if(i == 3) {
|
||||||
EXPECT_FALSE(iter.next());
|
++i;
|
||||||
}
|
}
|
||||||
op = iter.current();
|
CHECK_TRUE(q.pop());
|
||||||
}
|
}
|
||||||
|
|
||||||
// test that lock is held by iterator
|
// remove from start
|
||||||
EXPECT_FALSE(q.push_nb(10));
|
q.push(0);
|
||||||
op = q.top_nb();
|
q.push(1);
|
||||||
// Getting top and iterator both hold read locks so this should be true.
|
q.push(2);
|
||||||
EXPECT_TRUE(op);
|
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
|
// remove from end
|
||||||
EXPECT_TRUE(iter.prev());
|
q.push(0);
|
||||||
op = iter.current();
|
q.push(1);
|
||||||
while(op) {
|
q.push(2);
|
||||||
EXPECT_EQ(*op, --i);
|
q.push(3);
|
||||||
if(i > 0) {
|
CHECK_EQ(q.size(), 4);
|
||||||
EXPECT_TRUE(iter.prev());
|
{
|
||||||
} else {
|
auto iter = q.begin();
|
||||||
EXPECT_FALSE(iter.prev());
|
while(true) {
|
||||||
|
CHECK_TRUE(iter.next());
|
||||||
|
op = iter.current();
|
||||||
|
CHECK_TRUE(op);
|
||||||
|
if(*op == 3) {
|
||||||
|
CHECK_FALSE(iter.remove());
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
op = iter.current();
|
|
||||||
}
|
}
|
||||||
}
|
CHECK_EQ(q.size(), 3);
|
||||||
|
i = 0;
|
||||||
{
|
while(!q.empty()) {
|
||||||
// iter remove
|
op = q.top();
|
||||||
auto iter = q.begin();
|
CHECK_TRUE(op);
|
||||||
EXPECT_TRUE(iter.next());
|
CHECK_EQ(i++, *op);
|
||||||
EXPECT_TRUE(iter.next());
|
CHECK_TRUE(q.pop());
|
||||||
EXPECT_TRUE(iter.next());
|
if(i == 3) {
|
||||||
EXPECT_TRUE(iter.remove());
|
CHECK_TRUE(q.empty());
|
||||||
|
|
||||||
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<int> 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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EXPECT_EQ(q.size(), 3);
|
|
||||||
i = 0;
|
// TempToNew
|
||||||
while(!q.empty()) {
|
{
|
||||||
op = q.top();
|
TSLQueue<int> q;
|
||||||
EXPECT_TRUE(op);
|
|
||||||
EXPECT_EQ(i++, *op);
|
q.push(1234);
|
||||||
EXPECT_TRUE(q.pop());
|
q.push(5678);
|
||||||
if(i == 3) {
|
|
||||||
EXPECT_TRUE(q.empty());
|
auto getValue = [] (TSLQueue<int> *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<int> q;
|
|
||||||
|
|
||||||
q.push(1234);
|
|
||||||
q.push(5678);
|
|
||||||
|
|
||||||
auto getValue = [] (TSLQueue<int> *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);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,464 +1,478 @@
|
||||||
#include <gtest/gtest.h>
|
#include "test_headers.h"
|
||||||
|
#include "test_helpers.h"
|
||||||
|
|
||||||
#include <UDPC.h>
|
#include <UDPC.h>
|
||||||
#include <UDPC_Defines.hpp>
|
#include <UDPC_Defines.hpp>
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <future>
|
#include <future>
|
||||||
|
|
||||||
TEST(UDPC, atostr) {
|
void TEST_UDPC() {
|
||||||
UDPC::Context context(false);
|
// atostr
|
||||||
|
{
|
||||||
|
UDPC::Context context(false);
|
||||||
|
|
||||||
UDPC_ConnectionId conId;
|
UDPC_ConnectionId conId;
|
||||||
const char* resultBuf;
|
const char* resultBuf;
|
||||||
|
|
||||||
for(unsigned int i = 0; i < 16; ++i) {
|
for(unsigned int i = 0; i < 16; ++i) {
|
||||||
conId.addr.s6_addr[i] = (i % 3 == 0 ? 0xFF : (i % 3 == 1 ? 0x12 : 0x56));
|
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<void> 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) {
|
resultBuf = UDPC_atostr((UDPC_HContext)&context, conId.addr);
|
||||||
ASSERT_TRUE(futures[j].valid());
|
CHECK_STREQ(resultBuf, "ff12:56ff:1256:ff12:56ff:1256:ff12:56ff");
|
||||||
futures[j].wait();
|
|
||||||
|
for(unsigned int i = 0; i < 8; ++i) {
|
||||||
|
conId.addr.s6_addr[i] = 0;
|
||||||
}
|
}
|
||||||
for(unsigned int j = 0; j < 32; ++j) {
|
resultBuf = UDPC_atostr((UDPC_HContext)&context, conId.addr);
|
||||||
EXPECT_STREQ(ptrs[j], results[j]);
|
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<void> 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) {
|
// atostr_unsafe
|
||||||
const char* results[64] = {
|
{
|
||||||
"::1111:1",
|
const char* results[64] = {
|
||||||
"::1111:2",
|
"::1111:1",
|
||||||
"::1111:3",
|
"::1111:2",
|
||||||
"::1111:4",
|
"::1111:3",
|
||||||
"::1111:5",
|
"::1111:4",
|
||||||
"::1111:6",
|
"::1111:5",
|
||||||
"::1111:7",
|
"::1111:6",
|
||||||
"::1111:8",
|
"::1111:7",
|
||||||
"::1111:9",
|
"::1111:8",
|
||||||
"::1111:a",
|
"::1111:9",
|
||||||
"::1111:b",
|
"::1111:a",
|
||||||
"::1111:c",
|
"::1111:b",
|
||||||
"::1111:d",
|
"::1111:c",
|
||||||
"::1111:e",
|
"::1111:d",
|
||||||
"::1111:f",
|
"::1111:e",
|
||||||
"::1111:10",
|
"::1111:f",
|
||||||
"::1111:11",
|
"::1111:10",
|
||||||
"::1111:12",
|
"::1111:11",
|
||||||
"::1111:13",
|
"::1111:12",
|
||||||
"::1111:14",
|
"::1111:13",
|
||||||
"::1111:15",
|
"::1111:14",
|
||||||
"::1111:16",
|
"::1111:15",
|
||||||
"::1111:17",
|
"::1111:16",
|
||||||
"::1111:18",
|
"::1111:17",
|
||||||
"::1111:19",
|
"::1111:18",
|
||||||
"::1111:1a",
|
"::1111:19",
|
||||||
"::1111:1b",
|
"::1111:1a",
|
||||||
"::1111:1c",
|
"::1111:1b",
|
||||||
"::1111:1d",
|
"::1111:1c",
|
||||||
"::1111:1e",
|
"::1111:1d",
|
||||||
"::1111:1f",
|
"::1111:1e",
|
||||||
"::1111:20",
|
"::1111:1f",
|
||||||
"::1111:21",
|
"::1111:20",
|
||||||
"::1111:22",
|
"::1111:21",
|
||||||
"::1111:23",
|
"::1111:22",
|
||||||
"::1111:24",
|
"::1111:23",
|
||||||
"::1111:25",
|
"::1111:24",
|
||||||
"::1111:26",
|
"::1111:25",
|
||||||
"::1111:27",
|
"::1111:26",
|
||||||
"::1111:28",
|
"::1111:27",
|
||||||
"::1111:29",
|
"::1111:28",
|
||||||
"::1111:2a",
|
"::1111:29",
|
||||||
"::1111:2b",
|
"::1111:2a",
|
||||||
"::1111:2c",
|
"::1111:2b",
|
||||||
"::1111:2d",
|
"::1111:2c",
|
||||||
"::1111:2e",
|
"::1111:2d",
|
||||||
"::1111:2f",
|
"::1111:2e",
|
||||||
"::1111:30",
|
"::1111:2f",
|
||||||
"::1111:31",
|
"::1111:30",
|
||||||
"::1111:32",
|
"::1111:31",
|
||||||
"::1111:33",
|
"::1111:32",
|
||||||
"::1111:34",
|
"::1111:33",
|
||||||
"::1111:35",
|
"::1111:34",
|
||||||
"::1111:36",
|
"::1111:35",
|
||||||
"::1111:37",
|
"::1111:36",
|
||||||
"::1111:38",
|
"::1111:37",
|
||||||
"::1111:39",
|
"::1111:38",
|
||||||
"::1111:3a",
|
"::1111:39",
|
||||||
"::1111:3b",
|
"::1111:3a",
|
||||||
"::1111:3c",
|
"::1111:3b",
|
||||||
"::1111:3d",
|
"::1111:3c",
|
||||||
"::1111:3e",
|
"::1111:3d",
|
||||||
"::1111:3f",
|
"::1111:3e",
|
||||||
"::1111:40"
|
"::1111:3f",
|
||||||
};
|
"::1111:40"
|
||||||
std::future<void> futures[32];
|
};
|
||||||
const char* ptrs[32];
|
std::future<void> futures[32];
|
||||||
for(unsigned int i = 0; i < 2; ++i) {
|
const char* ptrs[32];
|
||||||
for(unsigned int j = 0; j < 32; ++j) {
|
for(unsigned int i = 0; i < 2; ++i) {
|
||||||
futures[j] = std::async(std::launch::async, [] (unsigned int id, const char** ptr) {
|
for(unsigned int j = 0; j < 32; ++j) {
|
||||||
UDPC_ConnectionId conId = {
|
futures[j] = std::async(std::launch::async, [] (unsigned int id, const char** ptr) {
|
||||||
{0, 0, 0, 0,
|
UDPC_ConnectionId conId = {
|
||||||
0, 0, 0, 0,
|
{0, 0, 0, 0,
|
||||||
0, 0, 0, 0,
|
0, 0, 0, 0,
|
||||||
0x11, 0x11, 0x0, (unsigned char)(id + 1)},
|
0, 0, 0, 0,
|
||||||
0,
|
0x11, 0x11, 0x0, (unsigned char)(id + 1)},
|
||||||
0
|
0,
|
||||||
};
|
0
|
||||||
ptr[id] = UDPC_atostr_unsafe(conId.addr);
|
};
|
||||||
}, j, ptrs);
|
ptr[id] = UDPC_atostr_unsafe(conId.addr);
|
||||||
}
|
}, j, ptrs);
|
||||||
for(unsigned int j = 0; j < 32; ++j) {
|
}
|
||||||
ASSERT_TRUE(futures[j].valid());
|
for(unsigned int j = 0; j < 32; ++j) {
|
||||||
futures[j].wait();
|
ASSERT_TRUE(futures[j].valid());
|
||||||
}
|
futures[j].wait();
|
||||||
for(unsigned int j = 0; j < 32; ++j) {
|
}
|
||||||
EXPECT_STREQ(ptrs[j], results[j]);
|
for(unsigned int j = 0; j < 32; ++j) {
|
||||||
UDPC_atostr_unsafe_free_ptr(ptrs + j);
|
CHECK_STREQ(ptrs[j], results[j]);
|
||||||
UDPC_atostr_unsafe_free_ptr(ptrs + j);
|
UDPC_atostr_unsafe_free_ptr(ptrs + j);
|
||||||
|
UDPC_atostr_unsafe_free_ptr(ptrs + j);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
TEST(UDPC, strtoa) {
|
// strtoa
|
||||||
struct in6_addr addr;
|
{
|
||||||
|
struct in6_addr addr;
|
||||||
|
|
||||||
for(unsigned int i = 0; i < 16; ++i) {
|
for(unsigned int i = 0; i < 16; ++i) {
|
||||||
addr.s6_addr[i] = 0;
|
addr.s6_addr[i] = 0;
|
||||||
}
|
}
|
||||||
addr.s6_addr[15] = 1;
|
addr.s6_addr[15] = 1;
|
||||||
|
|
||||||
EXPECT_EQ(UDPC_strtoa("::1"), addr);
|
CHECK_EQ(UDPC_strtoa("::1"), addr);
|
||||||
|
|
||||||
// check invalid
|
// check invalid
|
||||||
EXPECT_EQ(UDPC_strtoa("1:1::1:1::1"), addr);
|
CHECK_EQ(UDPC_strtoa("1:1::1:1::1"), addr);
|
||||||
EXPECT_EQ(UDPC_strtoa("derpadoodle"), addr);
|
CHECK_EQ(UDPC_strtoa("derpadoodle"), addr);
|
||||||
|
|
||||||
addr = {
|
addr = {
|
||||||
0xF0, 0xF, 0x0, 0x1,
|
0xF0, 0xF, 0x0, 0x1,
|
||||||
0x56, 0x78, 0x9A, 0xBC,
|
0x56, 0x78, 0x9A, 0xBC,
|
||||||
0xDE, 0xFF, 0x1, 0x2,
|
0xDE, 0xFF, 0x1, 0x2,
|
||||||
0x3, 0x4, 0x5, 0x6
|
0x3, 0x4, 0x5, 0x6
|
||||||
};
|
};
|
||||||
EXPECT_EQ(UDPC_strtoa("F00F:1:5678:9abc:deff:102:304:506"), addr);
|
CHECK_EQ(UDPC_strtoa("F00F:1:5678:9abc:deff:102:304:506"), addr);
|
||||||
|
|
||||||
addr = {
|
addr = {
|
||||||
0x0, 0xFF, 0x1, 0x0,
|
0x0, 0xFF, 0x1, 0x0,
|
||||||
0x0, 0x1, 0x10, 0x0,
|
0x0, 0x1, 0x10, 0x0,
|
||||||
0x0, 0x0, 0x0, 0x0,
|
0x0, 0x0, 0x0, 0x0,
|
||||||
0x12, 0x34, 0xab, 0xcd
|
0x12, 0x34, 0xab, 0xcd
|
||||||
};
|
};
|
||||||
EXPECT_EQ(UDPC_strtoa("ff:100:1:1000::1234:abcd"), addr);
|
CHECK_EQ(UDPC_strtoa("ff:100:1:1000::1234:abcd"), addr);
|
||||||
|
|
||||||
addr = {
|
addr = {
|
||||||
0x0, 0x0, 0x0, 0x0,
|
0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0, 0x0, 0x0,
|
0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0, 0xFF, 0xFF,
|
0x0, 0x0, 0xFF, 0xFF,
|
||||||
0x7F, 0x0, 0x0, 0x1
|
0x7F, 0x0, 0x0, 0x1
|
||||||
};
|
};
|
||||||
EXPECT_EQ(UDPC_strtoa("127.0.0.1"), addr);
|
CHECK_EQ(UDPC_strtoa("127.0.0.1"), addr);
|
||||||
|
|
||||||
addr = {
|
addr = {
|
||||||
0x0, 0x0, 0x0, 0x0,
|
0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0, 0x0, 0x0,
|
0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0, 0xFF, 0xFF,
|
0x0, 0x0, 0xFF, 0xFF,
|
||||||
0xA, 0x1, 0x2, 0x3
|
0xA, 0x1, 0x2, 0x3
|
||||||
};
|
};
|
||||||
EXPECT_EQ(UDPC_strtoa("10.1.2.3"), addr);
|
CHECK_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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
id = UDPC_create_id_full({0}, 0, 0);
|
// create_id_easy
|
||||||
for(unsigned int i = 0; i < sizeof(UDPC_ConnectionId); ++i) {
|
{
|
||||||
EXPECT_EQ(((char*)&id)[i], 0);
|
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);
|
// ConnectionIdBits
|
||||||
for(unsigned int i = 0; i < sizeof(UDPC_ConnectionId); ++i) {
|
{
|
||||||
EXPECT_EQ(((char*)&id)[i], 0);
|
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);
|
// NetworkOrderEndianness
|
||||||
for(unsigned int i = 0; i < sizeof(UDPC_ConnectionId); ++i) {
|
{
|
||||||
EXPECT_EQ(((char*)&id)[i], 0);
|
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) {
|
uint32_t l = 0x01020304;
|
||||||
if(UDPC_is_big_endian() != 0) {
|
l = UDPC_no32i(l);
|
||||||
puts("Is big-endian");
|
CHECK_EQ(l, 0x01020304);
|
||||||
uint16_t s = 0x0102;
|
|
||||||
s = UDPC_no16i(s);
|
|
||||||
EXPECT_EQ(s, 0x0102);
|
|
||||||
|
|
||||||
uint32_t l = 0x01020304;
|
uint64_t ll = 0x0102030405060708;
|
||||||
l = UDPC_no32i(l);
|
ll = UDPC_no64i(ll);
|
||||||
EXPECT_EQ(l, 0x01020304);
|
CHECK_EQ(ll, 0x0102030405060708);
|
||||||
|
|
||||||
uint64_t ll = 0x0102030405060708;
|
l = 0x40208040;
|
||||||
ll = UDPC_no64i(ll);
|
float *f = reinterpret_cast<float*>(&l);
|
||||||
EXPECT_EQ(ll, 0x0102030405060708);
|
*f = UDPC_no32f(*f);
|
||||||
|
CHECK_EQ(l, 0x40208040);
|
||||||
|
|
||||||
l = 0x40208040;
|
ll = 0x4000001010008040;
|
||||||
float *f = reinterpret_cast<float*>(&l);
|
double *d = reinterpret_cast<double*>(&ll);
|
||||||
*f = UDPC_no32f(*f);
|
*d = UDPC_no64f(*d);
|
||||||
EXPECT_EQ(l, 0x40208040);
|
CHECK_EQ(ll, 0x4000001010008040);
|
||||||
|
|
||||||
ll = 0x4000001010008040;
|
|
||||||
double *d = reinterpret_cast<double*>(&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<float*>(&l);
|
|
||||||
*f = UDPC_no32f(*f);
|
|
||||||
EXPECT_EQ(l, 0x40802040);
|
|
||||||
*f = UDPC_no32f(*f);
|
|
||||||
EXPECT_EQ(l, 0x40208040);
|
|
||||||
|
|
||||||
ll = 0x4000001010008040;
|
|
||||||
double *d = reinterpret_cast<double*>(&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<std::thread, 100> 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 {
|
} else {
|
||||||
thread_array[i] = std::thread([] (UDPC_HContext ctx) {
|
puts("Is NOT big-endian");
|
||||||
UDPC_disable_threaded_update(ctx);
|
uint16_t s = 0x0102;
|
||||||
}, ctx);
|
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<float*>(&l);
|
||||||
|
*f = UDPC_no32f(*f);
|
||||||
|
CHECK_EQ(l, 0x40802040);
|
||||||
|
*f = UDPC_no32f(*f);
|
||||||
|
CHECK_EQ(l, 0x40208040);
|
||||||
|
|
||||||
|
ll = 0x4000001010008040;
|
||||||
|
double *d = reinterpret_cast<double*>(&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) {
|
// free_packet_ptr
|
||||||
thread_array[i].join();
|
{
|
||||||
|
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<std::thread, 100> 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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,18 @@
|
||||||
#include <gtest/gtest.h>
|
#include "test_helpers.h"
|
||||||
|
#include "test_headers.h"
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int checks_checked = 0;
|
||||||
::testing::InitGoogleTest(&argc, argv);
|
int checks_passed = 0;
|
||||||
return RUN_ALL_TESTS();
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
10
src/test/test_headers.h
Normal file
10
src/test/test_headers.h
Normal file
|
@ -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
|
108
src/test/test_helpers.h
Normal file
108
src/test/test_helpers.h
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
#ifndef SEODISPARATE_COM_UDPC_TEST_HELPERS_H_
|
||||||
|
#define SEODISPARATE_COM_UDPC_TEST_HELPERS_H_
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
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
|
Loading…
Reference in a new issue