Rework unit-tests to not use GTest
All checks were successful
Publish doxygen documentation to seodisparate.com / doxygen-gen-and-publish (push) Successful in 2s
Run UnitTests / build-and-run-tests (push) Successful in 2m32s

This commit is contained in:
Stephen Seo 2024-07-12 15:52:53 +09:00
parent 510156bc58
commit c6b13de9f8
9 changed files with 852 additions and 702 deletions

View file

@ -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

View file

@ -59,9 +59,6 @@ else()
endif() endif()
if(CMAKE_BUILD_TYPE MATCHES "Debug") if(CMAKE_BUILD_TYPE MATCHES "Debug")
find_package(GTest QUIET)
if(GTEST_FOUND)
set(UDPC_UnitTest_SOURCES set(UDPC_UnitTest_SOURCES
src/CXX11_shared_spin_lock.cpp src/CXX11_shared_spin_lock.cpp
src/test/UDPC_UnitTest.cpp src/test/UDPC_UnitTest.cpp
@ -71,9 +68,9 @@ if(CMAKE_BUILD_TYPE MATCHES "Debug")
) )
add_executable(UnitTest ${UDPC_UnitTest_SOURCES}) add_executable(UnitTest ${UDPC_UnitTest_SOURCES})
target_compile_features(UnitTest PUBLIC cxx_std_11) target_compile_features(UnitTest PUBLIC cxx_std_11)
target_link_libraries(UnitTest PUBLIC UDPC ${GTEST_BOTH_LIBRARIES}) target_link_libraries(UnitTest PUBLIC UDPC)
target_include_directories(UnitTest PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src) target_include_directories(UnitTest PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src)
endif() target_compile_options(UnitTest PRIVATE "-Wno-sign-compare")
set(UDPC_NetworkTest_SOURCES set(UDPC_NetworkTest_SOURCES
src/test/UDPC_NetworkTest.c) src/test/UDPC_NetworkTest.c)

View file

@ -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

View file

@ -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());
} }

View file

@ -1,48 +1,52 @@
#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() {
// PushTopPopSize
{
TSLQueue<int> q; TSLQueue<int> q;
EXPECT_FALSE(q.top()); CHECK_FALSE(q.top());
for(int i = 0; i < 10; ++i) { for(int i = 0; i < 10; ++i) {
EXPECT_EQ(i, q.size()); CHECK_EQ(i, q.size());
q.push(i); q.push(i);
} }
for(int i = 0; i < 10; ++i) { for(int i = 0; i < 10; ++i) {
auto v = q.top(); auto v = q.top();
ASSERT_TRUE(v); ASSERT_TRUE(v);
EXPECT_EQ(*v, i); CHECK_EQ(*v, i);
EXPECT_EQ(10 - i, q.size()); CHECK_EQ(10 - i, q.size());
EXPECT_TRUE(q.pop()); CHECK_TRUE(q.pop());
} }
EXPECT_EQ(q.size(), 0); CHECK_EQ(q.size(), 0);
EXPECT_FALSE(q.pop()); CHECK_FALSE(q.pop());
} }
TEST(TSLQueue, PushNB_TopNB_TopAndPop_Size) { // PushNB_TopNB_TopAndPop_Size
{
TSLQueue<int> q; TSLQueue<int> q;
for(int i = 0; i < 10; ++i) { for(int i = 0; i < 10; ++i) {
EXPECT_EQ(q.size(), i); CHECK_EQ(q.size(), i);
EXPECT_TRUE(q.push_nb(i)); CHECK_TRUE(q.push_nb(i));
} }
for(int i = 0; i < 10; ++i) { for(int i = 0; i < 10; ++i) {
auto v = q.top_nb(); auto v = q.top_nb();
ASSERT_TRUE(v); ASSERT_TRUE(v);
EXPECT_EQ(*v, i); CHECK_EQ(*v, i);
EXPECT_EQ(q.size(), 10 - i); CHECK_EQ(q.size(), 10 - i);
v = q.top_and_pop(); v = q.top_and_pop();
ASSERT_TRUE(v); ASSERT_TRUE(v);
EXPECT_EQ(*v, i); CHECK_EQ(*v, i);
} }
{ {
@ -53,44 +57,47 @@ TEST(TSLQueue, PushNB_TopNB_TopAndPop_Size) {
auto v = q.top_and_pop(); auto v = q.top_and_pop();
ASSERT_FALSE(v); ASSERT_FALSE(v);
} }
EXPECT_EQ(q.size(), 0); CHECK_EQ(q.size(), 0);
} }
TEST(TSLQueue, Push_TopAndPopAndEmpty_Size) { // Push_TopAndPopAndEmpty_Size
{
TSLQueue<int> q; TSLQueue<int> q;
for(int i = 0; i < 10; ++i) { for(int i = 0; i < 10; ++i) {
EXPECT_EQ(q.size(), i); CHECK_EQ(q.size(), i);
q.push(i); q.push(i);
} }
bool isEmpty; bool isEmpty;
for(int i = 0; i < 10; ++i) { for(int i = 0; i < 10; ++i) {
EXPECT_EQ(q.size(), 10 - i); CHECK_EQ(q.size(), 10 - i);
auto v = q.top_and_pop_and_empty(&isEmpty); auto v = q.top_and_pop_and_empty(&isEmpty);
ASSERT_TRUE(v); ASSERT_TRUE(v);
EXPECT_EQ(*v, i); CHECK_EQ(*v, i);
EXPECT_EQ(i == 9, isEmpty); CHECK_EQ(i == 9, isEmpty);
} }
EXPECT_EQ(q.size(), 0); CHECK_EQ(q.size(), 0);
} }
TEST(TSLQueue, PushClearEmptySize) { // PushClearEmptySize
{
TSLQueue<int> q; TSLQueue<int> q;
for(int i = 0; i < 10; ++i) { for(int i = 0; i < 10; ++i) {
EXPECT_EQ(q.size(), i); CHECK_EQ(q.size(), i);
q.push(i); q.push(i);
} }
EXPECT_EQ(q.size(), 10); CHECK_EQ(q.size(), 10);
EXPECT_FALSE(q.empty()); CHECK_FALSE(q.empty());
q.clear(); q.clear();
EXPECT_TRUE(q.empty()); CHECK_TRUE(q.empty());
EXPECT_EQ(q.size(), 0); CHECK_EQ(q.size(), 0);
} }
TEST(TSLQueue, Concurrent) { // Concurrent
{
TSLQueue<int> q; TSLQueue<int> q;
const auto add_fn = [] (TSLQueue<int> *q, int i) -> void { const auto add_fn = [] (TSLQueue<int> *q, int i) -> void {
@ -105,25 +112,26 @@ TEST(TSLQueue, Concurrent) {
futures[i].wait(); futures[i].wait();
} }
EXPECT_FALSE(q.empty()); CHECK_FALSE(q.empty());
for(int i = 0; i < 100; ++i) { for(int i = 0; i < 100; ++i) {
EXPECT_EQ(q.size(), 100 - i); CHECK_EQ(q.size(), 100 - i);
auto v = q.top_and_pop(); auto v = q.top_and_pop();
ASSERT_TRUE(v); ASSERT_TRUE(v);
EXPECT_GE(*v, 0); CHECK_GE(*v, 0);
EXPECT_LE(*v, 100); CHECK_LE(*v, 100);
EXPECT_EQ(i == 99, q.empty()); CHECK_EQ(i == 99, q.empty());
} }
EXPECT_EQ(q.size(), 0); CHECK_EQ(q.size(), 0);
} }
TEST(TSLQueue, Iterator) { // Iterator
{
TSLQueue<int> q; TSLQueue<int> q;
for(int i = 0; i < 10; ++i) { for(int i = 0; i < 10; ++i) {
q.push(i); q.push(i);
} }
EXPECT_EQ(q.size(), 10); CHECK_EQ(q.size(), 10);
{ {
// iteration // iteration
@ -131,30 +139,30 @@ TEST(TSLQueue, Iterator) {
int i = 0; int i = 0;
auto op = iter.current(); auto op = iter.current();
while(op) { while(op) {
EXPECT_EQ(*op, i++); CHECK_EQ(*op, i++);
if(i < 10) { if(i < 10) {
EXPECT_TRUE(iter.next()); CHECK_TRUE(iter.next());
} else { } else {
EXPECT_FALSE(iter.next()); CHECK_FALSE(iter.next());
} }
op = iter.current(); op = iter.current();
} }
// test that lock is held by iterator // test that lock is held by iterator
EXPECT_FALSE(q.push_nb(10)); CHECK_FALSE(q.push_nb(10));
op = q.top_nb(); op = q.top_nb();
// Getting top and iterator both hold read locks so this should be true. // Getting top and iterator both hold read locks so this should be true.
EXPECT_TRUE(op); CHECK_TRUE(op);
// backwards iteration // backwards iteration
EXPECT_TRUE(iter.prev()); CHECK_TRUE(iter.prev());
op = iter.current(); op = iter.current();
while(op) { while(op) {
EXPECT_EQ(*op, --i); CHECK_EQ(*op, --i);
if(i > 0) { if(i > 0) {
EXPECT_TRUE(iter.prev()); CHECK_TRUE(iter.prev());
} else { } else {
EXPECT_FALSE(iter.prev()); CHECK_FALSE(iter.prev());
} }
op = iter.current(); op = iter.current();
} }
@ -163,48 +171,48 @@ TEST(TSLQueue, Iterator) {
{ {
// iter remove // iter remove
auto iter = q.begin(); auto iter = q.begin();
EXPECT_TRUE(iter.next()); CHECK_TRUE(iter.next());
EXPECT_TRUE(iter.next()); CHECK_TRUE(iter.next());
EXPECT_TRUE(iter.next()); CHECK_TRUE(iter.next());
EXPECT_TRUE(iter.remove()); CHECK_TRUE(iter.remove());
auto op = iter.current(); auto op = iter.current();
EXPECT_TRUE(op); CHECK_TRUE(op);
EXPECT_EQ(*op, 4); CHECK_EQ(*op, 4);
EXPECT_TRUE(iter.prev()); CHECK_TRUE(iter.prev());
op = iter.current(); op = iter.current();
EXPECT_TRUE(op); CHECK_TRUE(op);
EXPECT_EQ(*op, 2); CHECK_EQ(*op, 2);
// second iterator // second iterator
auto iter2 = q.begin(); auto iter2 = q.begin();
// Still should be able to get top. // Still should be able to get top.
EXPECT_TRUE(iter2.current()); CHECK_TRUE(iter2.current());
// Shouldn't be able to remove if 2 iterators exist. // Shouldn't be able to remove if 2 iterators exist.
EXPECT_FALSE(iter2.try_remove()); CHECK_FALSE(iter2.try_remove());
// This will never return since the first iterator has a "read" lock. // This will never return since the first iterator has a "read" lock.
//EXPECT_FALSE(iter2.remove()); //CHECK_FALSE(iter2.remove());
// Still should be able to get top. // Still should be able to get top.
EXPECT_TRUE(iter2.current()); CHECK_TRUE(iter2.current());
} }
EXPECT_EQ(q.size(), 9); CHECK_EQ(q.size(), 9);
// check that "3" was removed from queue // check that "3" was removed from queue
int i = 0; int i = 0;
std::unique_ptr<int> op; std::unique_ptr<int> op;
while(!q.empty()) { while(!q.empty()) {
op = q.top(); op = q.top();
EXPECT_TRUE(op); CHECK_TRUE(op);
EXPECT_EQ(i++, *op); CHECK_EQ(i++, *op);
if(i == 3) { if(i == 3) {
++i; ++i;
} }
EXPECT_TRUE(q.pop()); CHECK_TRUE(q.pop());
} }
// remove from start // remove from start
@ -212,18 +220,18 @@ TEST(TSLQueue, Iterator) {
q.push(1); q.push(1);
q.push(2); q.push(2);
q.push(3); q.push(3);
EXPECT_EQ(q.size(), 4); CHECK_EQ(q.size(), 4);
{ {
auto iter = q.begin(); auto iter = q.begin();
EXPECT_TRUE(iter.remove()); CHECK_TRUE(iter.remove());
} }
EXPECT_EQ(q.size(), 3); CHECK_EQ(q.size(), 3);
i = 1; i = 1;
while(!q.empty()) { while(!q.empty()) {
op = q.top(); op = q.top();
EXPECT_TRUE(op); CHECK_TRUE(op);
EXPECT_EQ(i++, *op); CHECK_EQ(i++, *op);
EXPECT_TRUE(q.pop()); CHECK_TRUE(q.pop());
} }
// remove from end // remove from end
@ -231,33 +239,34 @@ TEST(TSLQueue, Iterator) {
q.push(1); q.push(1);
q.push(2); q.push(2);
q.push(3); q.push(3);
EXPECT_EQ(q.size(), 4); CHECK_EQ(q.size(), 4);
{ {
auto iter = q.begin(); auto iter = q.begin();
while(true) { while(true) {
EXPECT_TRUE(iter.next()); CHECK_TRUE(iter.next());
op = iter.current(); op = iter.current();
EXPECT_TRUE(op); CHECK_TRUE(op);
if(*op == 3) { if(*op == 3) {
EXPECT_FALSE(iter.remove()); CHECK_FALSE(iter.remove());
break; break;
} }
} }
} }
EXPECT_EQ(q.size(), 3); CHECK_EQ(q.size(), 3);
i = 0; i = 0;
while(!q.empty()) { while(!q.empty()) {
op = q.top(); op = q.top();
EXPECT_TRUE(op); CHECK_TRUE(op);
EXPECT_EQ(i++, *op); CHECK_EQ(i++, *op);
EXPECT_TRUE(q.pop()); CHECK_TRUE(q.pop());
if(i == 3) { if(i == 3) {
EXPECT_TRUE(q.empty()); CHECK_TRUE(q.empty());
} }
} }
} }
TEST(TSLQueue, TempToNew) { // TempToNew
{
TSLQueue<int> q; TSLQueue<int> q;
q.push(1234); q.push(1234);
@ -270,7 +279,8 @@ TEST(TSLQueue, TempToNew) {
int value; int value;
value = getValue(&q); value = getValue(&q);
EXPECT_EQ(1234, value); CHECK_EQ(1234, value);
value = getValue(&q); value = getValue(&q);
EXPECT_EQ(5678, value); CHECK_EQ(5678, value);
}
} }

View file

@ -1,14 +1,18 @@
#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() {
// atostr
{
UDPC::Context context(false); UDPC::Context context(false);
UDPC_ConnectionId conId; UDPC_ConnectionId conId;
@ -18,23 +22,23 @@ TEST(UDPC, atostr) {
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); resultBuf = UDPC_atostr((UDPC_HContext)&context, conId.addr);
EXPECT_STREQ(resultBuf, "ff12:56ff:1256:ff12:56ff:1256:ff12:56ff"); CHECK_STREQ(resultBuf, "ff12:56ff:1256:ff12:56ff:1256:ff12:56ff");
for(unsigned int i = 0; i < 8; ++i) { for(unsigned int i = 0; i < 8; ++i) {
conId.addr.s6_addr[i] = 0; conId.addr.s6_addr[i] = 0;
} }
resultBuf = UDPC_atostr((UDPC_HContext)&context, conId.addr); resultBuf = UDPC_atostr((UDPC_HContext)&context, conId.addr);
EXPECT_STREQ(resultBuf, "::56ff:1256:ff12:56ff"); CHECK_STREQ(resultBuf, "::56ff:1256:ff12:56ff");
conId.addr.s6_addr[0] = 1; conId.addr.s6_addr[0] = 1;
conId.addr.s6_addr[1] = 2; conId.addr.s6_addr[1] = 2;
resultBuf = UDPC_atostr((UDPC_HContext)&context, conId.addr); resultBuf = UDPC_atostr((UDPC_HContext)&context, conId.addr);
EXPECT_STREQ(resultBuf, "102::56ff:1256:ff12:56ff"); CHECK_STREQ(resultBuf, "102::56ff:1256:ff12:56ff");
conId.addr.s6_addr[14] = 0; conId.addr.s6_addr[14] = 0;
conId.addr.s6_addr[15] = 0; conId.addr.s6_addr[15] = 0;
resultBuf = UDPC_atostr((UDPC_HContext)&context, conId.addr); resultBuf = UDPC_atostr((UDPC_HContext)&context, conId.addr);
EXPECT_STREQ(resultBuf, "102::56ff:1256:ff12:0"); CHECK_STREQ(resultBuf, "102::56ff:1256:ff12:0");
for(unsigned int i = 0; i < 15; ++i) { for(unsigned int i = 0; i < 15; ++i) {
conId.addr.s6_addr[i] = 0; conId.addr.s6_addr[i] = 0;
@ -42,12 +46,12 @@ TEST(UDPC, atostr) {
conId.addr.s6_addr[15] = 1; conId.addr.s6_addr[15] = 1;
resultBuf = UDPC_atostr((UDPC_HContext)&context, conId.addr); resultBuf = UDPC_atostr((UDPC_HContext)&context, conId.addr);
EXPECT_STREQ(resultBuf, "::1"); CHECK_STREQ(resultBuf, "::1");
conId.addr.s6_addr[15] = 0; conId.addr.s6_addr[15] = 0;
resultBuf = UDPC_atostr((UDPC_HContext)&context, conId.addr); resultBuf = UDPC_atostr((UDPC_HContext)&context, conId.addr);
EXPECT_STREQ(resultBuf, "::"); CHECK_STREQ(resultBuf, "::");
conId.addr = { conId.addr = {
0xAE, 0x0, 0x12, 1, 0xAE, 0x0, 0x12, 1,
@ -56,10 +60,11 @@ TEST(UDPC, atostr) {
0, 0, 0, 0 0, 0, 0, 0
}; };
resultBuf = UDPC_atostr((UDPC_HContext)&context, conId.addr); resultBuf = UDPC_atostr((UDPC_HContext)&context, conId.addr);
EXPECT_STREQ(resultBuf, "ae00:1201:1045:213::"); CHECK_STREQ(resultBuf, "ae00:1201:1045:213::");
} }
TEST(UDPC, atostr_concurrent) { // atostr_concurrent
{
UDPC::Context context(false); UDPC::Context context(false);
const char* results[64] = { const char* results[64] = {
@ -150,12 +155,13 @@ TEST(UDPC, atostr_concurrent) {
futures[j].wait(); futures[j].wait();
} }
for(unsigned int j = 0; j < 32; ++j) { for(unsigned int j = 0; j < 32; ++j) {
EXPECT_STREQ(ptrs[j], results[j]); CHECK_STREQ(ptrs[j], results[j]);
} }
} }
} }
TEST(UDPC, atostr_unsafe) { // atostr_unsafe
{
const char* results[64] = { const char* results[64] = {
"::1111:1", "::1111:1",
"::1111:2", "::1111:2",
@ -243,14 +249,15 @@ TEST(UDPC, atostr_unsafe) {
futures[j].wait(); futures[j].wait();
} }
for(unsigned int j = 0; j < 32; ++j) { for(unsigned int j = 0; j < 32; ++j) {
EXPECT_STREQ(ptrs[j], results[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); 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) {
@ -258,11 +265,11 @@ TEST(UDPC, strtoa) {
} }
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,
@ -270,7 +277,7 @@ TEST(UDPC, strtoa) {
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,
@ -278,7 +285,7 @@ TEST(UDPC, strtoa) {
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,
@ -286,7 +293,7 @@ TEST(UDPC, strtoa) {
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,
@ -294,138 +301,143 @@ TEST(UDPC, strtoa) {
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) { // create_id_easy
{
UDPC_ConnectionId conId; UDPC_ConnectionId conId;
// not link local // not link local
conId = UDPC_create_id_easy("::FFFF:7F00:1", 301); conId = UDPC_create_id_easy("::FFFF:7F00:1", 301);
for(unsigned int i = 0; i < 10; ++i) { for(unsigned int i = 0; i < 10; ++i) {
EXPECT_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[i], 0); CHECK_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[i], 0);
} }
EXPECT_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[10], 0xFF); CHECK_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[10], 0xFF);
EXPECT_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[11], 0xFF); CHECK_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[11], 0xFF);
EXPECT_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[12], 0x7F); CHECK_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[12], 0x7F);
EXPECT_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[13], 0); CHECK_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[13], 0);
EXPECT_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[14], 0); CHECK_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[14], 0);
EXPECT_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[15], 0x1); CHECK_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[15], 0x1);
EXPECT_EQ(conId.scope_id, 0); CHECK_EQ(conId.scope_id, 0);
EXPECT_EQ(conId.port, 301); CHECK_EQ(conId.port, 301);
// link local // link local
conId = UDPC_create_id_easy("fe80::1234:5678:9%3", 123); conId = UDPC_create_id_easy("fe80::1234:5678:9%3", 123);
EXPECT_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[0], 0xFE); CHECK_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[0], 0xFE);
EXPECT_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[1], 0x80); CHECK_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[1], 0x80);
for(unsigned int i = 2; i < 10; ++i) { for(unsigned int i = 2; i < 10; ++i) {
EXPECT_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[i], 0); CHECK_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[i], 0);
} }
EXPECT_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[10], 0x12); CHECK_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[10], 0x12);
EXPECT_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[11], 0x34); CHECK_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[11], 0x34);
EXPECT_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[12], 0x56); CHECK_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[12], 0x56);
EXPECT_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[13], 0x78); CHECK_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[13], 0x78);
EXPECT_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[14], 0); CHECK_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[14], 0);
EXPECT_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[15], 0x9); CHECK_EQ(UDPC_IPV6_ADDR_SUB(conId.addr)[15], 0x9);
EXPECT_EQ(conId.scope_id, 3); CHECK_EQ(conId.scope_id, 3);
EXPECT_EQ(conId.port, 123); CHECK_EQ(conId.port, 123);
} }
TEST(UDPC, ConnectionIdBits) { // ConnectionIdBits
{
UDPC_ConnectionId id = UDPC_create_id({0}, 0); UDPC_ConnectionId id = UDPC_create_id({0}, 0);
for(unsigned int i = 0; i < sizeof(UDPC_ConnectionId); ++i) { for(unsigned int i = 0; i < sizeof(UDPC_ConnectionId); ++i) {
EXPECT_EQ(((char*)&id)[i], 0); CHECK_EQ(((char*)&id)[i], 0);
} }
id = UDPC_create_id_full({0}, 0, 0); id = UDPC_create_id_full({0}, 0, 0);
for(unsigned int i = 0; i < sizeof(UDPC_ConnectionId); ++i) { for(unsigned int i = 0; i < sizeof(UDPC_ConnectionId); ++i) {
EXPECT_EQ(((char*)&id)[i], 0); CHECK_EQ(((char*)&id)[i], 0);
} }
id = UDPC_create_id_anyaddr(0); id = UDPC_create_id_anyaddr(0);
for(unsigned int i = 0; i < sizeof(UDPC_ConnectionId); ++i) { for(unsigned int i = 0; i < sizeof(UDPC_ConnectionId); ++i) {
EXPECT_EQ(((char*)&id)[i], 0); CHECK_EQ(((char*)&id)[i], 0);
} }
id = UDPC_create_id_easy("::", 0); id = UDPC_create_id_easy("::", 0);
for(unsigned int i = 0; i < sizeof(UDPC_ConnectionId); ++i) { for(unsigned int i = 0; i < sizeof(UDPC_ConnectionId); ++i) {
EXPECT_EQ(((char*)&id)[i], 0); CHECK_EQ(((char*)&id)[i], 0);
} }
} }
TEST(UDPC, NetworkOrderEndianness) { // NetworkOrderEndianness
{
if(UDPC_is_big_endian() != 0) { if(UDPC_is_big_endian() != 0) {
puts("Is big-endian"); puts("Is big-endian");
uint16_t s = 0x0102; uint16_t s = 0x0102;
s = UDPC_no16i(s); s = UDPC_no16i(s);
EXPECT_EQ(s, 0x0102); CHECK_EQ(s, 0x0102);
uint32_t l = 0x01020304; uint32_t l = 0x01020304;
l = UDPC_no32i(l); l = UDPC_no32i(l);
EXPECT_EQ(l, 0x01020304); CHECK_EQ(l, 0x01020304);
uint64_t ll = 0x0102030405060708; uint64_t ll = 0x0102030405060708;
ll = UDPC_no64i(ll); ll = UDPC_no64i(ll);
EXPECT_EQ(ll, 0x0102030405060708); CHECK_EQ(ll, 0x0102030405060708);
l = 0x40208040; l = 0x40208040;
float *f = reinterpret_cast<float*>(&l); float *f = reinterpret_cast<float*>(&l);
*f = UDPC_no32f(*f); *f = UDPC_no32f(*f);
EXPECT_EQ(l, 0x40208040); CHECK_EQ(l, 0x40208040);
ll = 0x4000001010008040; ll = 0x4000001010008040;
double *d = reinterpret_cast<double*>(&ll); double *d = reinterpret_cast<double*>(&ll);
*d = UDPC_no64f(*d); *d = UDPC_no64f(*d);
EXPECT_EQ(ll, 0x4000001010008040); CHECK_EQ(ll, 0x4000001010008040);
} else { } else {
puts("Is NOT big-endian"); puts("Is NOT big-endian");
uint16_t s = 0x0102; uint16_t s = 0x0102;
s = UDPC_no16i(s); s = UDPC_no16i(s);
EXPECT_EQ(s, 0x0201); CHECK_EQ(s, 0x0201);
s = UDPC_no16i(s); s = UDPC_no16i(s);
EXPECT_EQ(s, 0x0102); CHECK_EQ(s, 0x0102);
uint32_t l = 0x01020304; uint32_t l = 0x01020304;
l = UDPC_no32i(l); l = UDPC_no32i(l);
EXPECT_EQ(l, 0x04030201); CHECK_EQ(l, 0x04030201);
l = UDPC_no32i(l); l = UDPC_no32i(l);
EXPECT_EQ(l, 0x01020304); CHECK_EQ(l, 0x01020304);
uint64_t ll = 0x0102030405060708; uint64_t ll = 0x0102030405060708;
ll = UDPC_no64i(ll); ll = UDPC_no64i(ll);
EXPECT_EQ(ll, 0x0807060504030201); CHECK_EQ(ll, 0x0807060504030201);
ll = UDPC_no64i(ll); ll = UDPC_no64i(ll);
EXPECT_EQ(ll, 0x0102030405060708); CHECK_EQ(ll, 0x0102030405060708);
l = 0x40208040; l = 0x40208040;
float *f = reinterpret_cast<float*>(&l); float *f = reinterpret_cast<float*>(&l);
*f = UDPC_no32f(*f); *f = UDPC_no32f(*f);
EXPECT_EQ(l, 0x40802040); CHECK_EQ(l, 0x40802040);
*f = UDPC_no32f(*f); *f = UDPC_no32f(*f);
EXPECT_EQ(l, 0x40208040); CHECK_EQ(l, 0x40208040);
ll = 0x4000001010008040; ll = 0x4000001010008040;
double *d = reinterpret_cast<double*>(&ll); double *d = reinterpret_cast<double*>(&ll);
*d = UDPC_no64f(*d); *d = UDPC_no64f(*d);
EXPECT_EQ(ll, 0x4080001010000040); CHECK_EQ(ll, 0x4080001010000040);
*d = UDPC_no64f(*d); *d = UDPC_no64f(*d);
EXPECT_EQ(ll, 0x4000001010008040); CHECK_EQ(ll, 0x4000001010008040);
} }
} }
TEST(UDPC, a4toa6) { // a4toa6
EXPECT_EQ(UDPC_a4toa6(0), in6addr_any); {
CHECK_EQ(UDPC_a4toa6(0), in6addr_any);
uint32_t a4 = htonl(0x7F000001); uint32_t a4 = htonl(0x7F000001);
EXPECT_EQ(UDPC_a4toa6(a4), in6addr_loopback); CHECK_EQ(UDPC_a4toa6(a4), in6addr_loopback);
UDPC_IPV6_ADDR_TYPE a6 = UDPC_strtoa("::FFFF:0102:0304"); UDPC_IPV6_ADDR_TYPE a6 = UDPC_strtoa("::FFFF:0102:0304");
a4 = htonl(0x01020304); a4 = htonl(0x01020304);
EXPECT_EQ(UDPC_a4toa6(a4), a6); CHECK_EQ(UDPC_a4toa6(a4), a6);
} }
TEST(UDPC, free_packet_ptr) { // free_packet_ptr
{
UDPC_PacketInfo pinfo; UDPC_PacketInfo pinfo;
pinfo.dataSize = 8; pinfo.dataSize = 8;
pinfo.data = (char*)std::malloc(pinfo.dataSize); pinfo.data = (char*)std::malloc(pinfo.dataSize);
@ -435,7 +447,8 @@ TEST(UDPC, free_packet_ptr) {
UDPC_free_PacketInfo_ptr(nullptr); UDPC_free_PacketInfo_ptr(nullptr);
} }
TEST(UDPC, enableDisableThreadedUpdate_StressTest) { // enableDisableThreadedUpdate_StressTest
{
UDPC_ConnectionId id = UDPC_create_id_anyaddr(0); UDPC_ConnectionId id = UDPC_create_id_anyaddr(0);
UDPC_HContext ctx = UDPC_init(id, 0, 0); UDPC_HContext ctx = UDPC_init(id, 0, 0);
@ -462,3 +475,4 @@ TEST(UDPC, enableDisableThreadedUpdate_StressTest) {
thread_array[i].join(); thread_array[i].join();
} }
} }
}

View file

@ -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
View 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
View 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