Skip to content
Snippets Groups Projects
Unverified Commit 1c10872e authored by Sébastien Blin's avatar Sébastien Blin
Browse files

tests: add unit tests structure to opendht

+ Unit testing requires cppunit.
+ add options for CMake and Autotools to build opendht_unit_tests.
+ add sample tests for InfoHash
+ modify Dockerfiles and Travis build to run `make test`
+ Change lowbit signature to return an int instead of an unsigned.
parent d7c0e9af
Branches
Tags
No related merge requests found
...@@ -48,6 +48,7 @@ Makefile.in ...@@ -48,6 +48,7 @@ Makefile.in
# Python # Python
*.pyc *.pyc
*.stamp
python/opendht.cpp python/opendht.cpp
python/setup.py python/setup.py
...@@ -60,3 +61,6 @@ doc/Doxyfile ...@@ -60,3 +61,6 @@ doc/Doxyfile
# vim swap files # vim swap files
*.swp *.swp
*.swo *.swo
# build dir
build
...@@ -58,7 +58,7 @@ script: ...@@ -58,7 +58,7 @@ script:
else else
options+='-DOPENDHT_PUSH_NOTIFICATIONS=OFF '; options+='-DOPENDHT_PUSH_NOTIFICATIONS=OFF ';
fi fi
docker run opendht-proxy /bin/sh -c "cd /root/opendht && mkdir build && cd build && cmake -DCMAKE_INSTALL_PREFIX=/usr -DOPENDHT_PYTHON=ON -DOPENDHT_LTO=ON $options .. && make -j8 && make install"; docker run opendht-proxy /bin/sh -c "cd /root/opendht && mkdir build && cd build && cmake -DCMAKE_INSTALL_PREFIX=/usr -DOPENDHT_PYTHON=ON -DOPENDHT_LTO=ON -DOPENDHT_TESTS=ON $options .. && make -j8 && ./opendht_unit_tests && make install";
fi fi
- | - |
......
...@@ -20,7 +20,9 @@ option (OPENDHT_PROXY_SERVER "Enable DHT proxy server, use Restbed and jsoncpp" ...@@ -20,7 +20,9 @@ option (OPENDHT_PROXY_SERVER "Enable DHT proxy server, use Restbed and jsoncpp"
option (OPENDHT_PUSH_NOTIFICATIONS "Enable push notifications support" OFF) option (OPENDHT_PUSH_NOTIFICATIONS "Enable push notifications support" OFF)
option (OPENDHT_PROXY_SERVER_IDENTITY "Allow clients to use the node identity" OFF) option (OPENDHT_PROXY_SERVER_IDENTITY "Allow clients to use the node identity" OFF)
option (OPENDHT_PROXY_CLIENT "Enable DHT proxy client, use Restbed and jsoncpp" OFF) option (OPENDHT_PROXY_CLIENT "Enable DHT proxy client, use Restbed and jsoncpp" OFF)
option (OPENDHT_INDEX "Build DHT indexation feature" ON) option (OPENDHT_INDEX "Build DHT indexation feature" OFF)
option (OPENDHT_TESTS "Add unit tests executable" OFF)
find_package(Doxygen) find_package(Doxygen)
option (OPENDHT_DOCUMENTATION "Create and install the HTML based API documentation (requires Doxygen)" ${DOXYGEN_FOUND}) option (OPENDHT_DOCUMENTATION "Create and install the HTML based API documentation (requires Doxygen)" ${DOXYGEN_FOUND})
...@@ -292,3 +294,26 @@ install (DIRECTORY include DESTINATION ${CMAKE_INSTALL_PREFIX}) ...@@ -292,3 +294,26 @@ install (DIRECTORY include DESTINATION ${CMAKE_INSTALL_PREFIX})
install (FILES ${CMAKE_CURRENT_BINARY_DIR}/opendht.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) install (FILES ${CMAKE_CURRENT_BINARY_DIR}/opendht.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
install (EXPORT opendht DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/opendht FILE opendhtConfig.cmake) install (EXPORT opendht DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/opendht FILE opendhtConfig.cmake)
install (FILES ${CMAKE_CURRENT_BINARY_DIR}/opendhtConfigVersion.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/opendht) install (FILES ${CMAKE_CURRENT_BINARY_DIR}/opendhtConfigVersion.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/opendht)
# Unit tests
IF(OPENDHT_TESTS)
FIND_PACKAGE(Cppunit REQUIRED)
# unit testing
add_executable(opendht_unit_tests
tests/tests_runner.cpp
tests/infohashtester.h
tests/infohashtester.cpp
)
if (OPENDHT_SHARED)
TARGET_LINK_LIBRARIES(opendht_unit_tests opendht)
else ()
TARGET_LINK_LIBRARIES(opendht_unit_tests opendht-static)
endif ()
TARGET_LINK_LIBRARIES(opendht_unit_tests
${CMAKE_THREAD_LIBS_INIT}
${CPPUNIT_LIBRARIES}
${GNUTLS_LIBRARIES}
)
enable_testing()
add_test(TEST opendht_unit_tests)
ENDIF()
...@@ -12,7 +12,7 @@ if USE_CYTHON ...@@ -12,7 +12,7 @@ if USE_CYTHON
SUBDIRS += python SUBDIRS += python
endif endif
SUBDIRS += doc SUBDIRS += doc tests
ACLOCAL_AMFLAGS = -I m4 ACLOCAL_AMFLAGS = -I m4
......
INCLUDE(FindPkgConfig)
PKG_CHECK_MODULES(PC_CPPUNIT "cppunit")
FIND_PATH(CPPUNIT_INCLUDE_DIRS
NAMES cppunit/TestCase.h
HINTS ${PC_CPPUNIT_INCLUDE_DIR}
${CMAKE_INSTALL_PREFIX}/include
PATHS
/usr/local/include
/usr/include
)
FIND_LIBRARY(CPPUNIT_LIBRARIES
NAMES cppunit
HINTS ${PC_CPPUNIT_LIBDIR}
${CMAKE_INSTALL_PREFIX}/lib
${CMAKE_INSTALL_PREFIX}/lib64
PATHS
${CPPUNIT_INCLUDE_DIRS}/../lib
/usr/local/lib
/usr/lib
)
LIST(APPEND CPPUNIT_LIBRARIES ${CMAKE_DL_LIBS})
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(CPPUNIT DEFAULT_MSG CPPUNIT_LIBRARIES CPPUNIT_INCLUDE_DIRS)
MARK_AS_ADVANCED(CPPUNIT_LIBRARIES CPPUNIT_INCLUDE_DIRS)
...@@ -182,6 +182,11 @@ AM_COND_IF([PROXY_CLIENT_OR_SERVER], [ ...@@ -182,6 +182,11 @@ AM_COND_IF([PROXY_CLIENT_OR_SERVER], [
LDFLAGS="${LDFLAGS} ${Jsoncpp_LIBS} -lrestbed" LDFLAGS="${LDFLAGS} ${Jsoncpp_LIBS} -lrestbed"
], []) ], [])
AC_ARG_ENABLE([tests], AS_HELP_STRING([--enable-tests], [Enable tests]), build_tests=yes, build_tests=no)
AM_CONDITIONAL(OPENDHT_TESTS, test x$build_tests == xyes)
AM_COND_IF([OPENDHT_TESTS], [
PKG_CHECK_MODULES([CppUnit], [cppunit >= 1.12])
])
AC_CONFIG_FILES([doc/Doxyfile doc/Makefile]) AC_CONFIG_FILES([doc/Doxyfile doc/Makefile])
...@@ -197,5 +202,6 @@ AM_COND_IF([USE_CYTHON], [ ...@@ -197,5 +202,6 @@ AM_COND_IF([USE_CYTHON], [
AC_CONFIG_FILES([Makefile AC_CONFIG_FILES([Makefile
src/Makefile src/Makefile
tools/Makefile tools/Makefile
tests/Makefile
opendht.pc]) opendht.pc])
AC_OUTPUT AC_OUTPUT
FROM ubuntu:17.04 FROM ubuntu:17.04
MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com> MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
RUN apt-get update && apt-get install -y build-essential cmake git wget libncurses5-dev libreadline-dev nettle-dev libgnutls28-dev libuv1-dev libmsgpack-dev libargon2-0-dev cython3 python3-dev python3-setuptools && apt-get clean RUN apt-get update && apt-get install -y build-essential cmake git wget libncurses5-dev libreadline-dev nettle-dev libgnutls28-dev libuv1-dev libmsgpack-dev libargon2-0-dev cython3 python3-dev libcppunit-dev python3-setuptools && apt-get clean
\ No newline at end of file
FROM ubuntu:17.04 FROM ubuntu:17.04
MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com> MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
RUN apt-get update \ RUN apt-get update \
&& apt-get install -y llvm llvm-dev clang make cmake git wget libncurses5-dev libreadline-dev nettle-dev libgnutls28-dev libuv1-dev libmsgpack-dev libargon2-0-dev cython3 python3-dev python3-setuptools \ && apt-get install -y llvm llvm-dev clang make cmake git wget libncurses5-dev libreadline-dev nettle-dev libgnutls28-dev libuv1-dev libmsgpack-dev libargon2-0-dev cython3 python3-dev python3-setuptools libcppunit-dev \
&& apt-get remove -y gcc g++ && apt-get autoremove -y && apt-get clean && apt-get remove -y gcc g++ && apt-get autoremove -y && apt-get clean
ENV CC cc ENV CC cc
ENV CXX c++ ENV CXX c++
FROM aberaud/opendht-deps FROM aberaud/opendht-deps
MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com> MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
RUN apt-get install -y libcppunit-dev # temp while aberaud/opendht-deps doesn't have this
COPY . /root/opendht COPY . /root/opendht
RUN cd /root/opendht && mkdir build && cd build \ RUN cd /root/opendht && mkdir build && cd build \
&& cmake -DCMAKE_INSTALL_PREFIX=/usr -DOPENDHT_PYTHON=On -DOPENDHT_LTO=On .. && make -j8 && make install && cmake -DCMAKE_INSTALL_PREFIX=/usr -DOPENDHT_PYTHON=On -DOPENDHT_LTO=On -DOPENDHT_TESTS=ON .. \
&& make -j8 && ./opendht_unit_tests && make install
FROM aberaud/opendht-deps-llvm FROM aberaud/opendht-deps-llvm
MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com> MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
RUN apt-get install -y libcppunit-dev # temp while aberaud/opendht-deps doesn't have this
COPY . /root/opendht COPY . /root/opendht
RUN cd /root/opendht && mkdir build && cd build \ RUN cd /root/opendht && mkdir build && cd build \
&& cmake -DCMAKE_INSTALL_PREFIX=/usr -DOPENDHT_PYTHON=On .. && make -j8 && make install && cmake -DCMAKE_INSTALL_PREFIX=/usr -DOPENDHT_PYTHON=On -DOPENDHT_TESTS=ON .. \
&& make -j8 && ./opendht_unit_tests && make install
FROM opendht-deps-proxy FROM opendht-deps-proxy
MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com> MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
RUN apt-get install -y libcppunit-dev # temp while aberaud/opendht-deps doesn't have this
COPY . /root/opendht COPY . /root/opendht
...@@ -129,7 +129,7 @@ public: ...@@ -129,7 +129,7 @@ public:
* Find the lowest 1 bit in an id. * Find the lowest 1 bit in an id.
* Result will allways be lower than 8*N * Result will allways be lower than 8*N
*/ */
inline unsigned lowbit() const { inline int lowbit() const {
int i, j; int i, j;
for(i = N-1; i >= 0; i--) for(i = N-1; i >= 0; i--)
if(data_[i] != 0) if(data_[i] != 0)
......
if OPENDHT_TESTS
bin_PROGRAMS = opendht_unit_tests
AM_CPPFLAGS = -I../include
opendht_unit_tests_SOURCES = tests_runner.cpp infohashtester.cpp
opendht_unit_tests_HEADERS = infohashtester.h
opendht_unit_tests_LDFLAGS = -lopendht -lcppunit -L@top_builddir@/src/.libs @Argon2_LDFLAGS@ @GnuTLS_LIBS@
endif
/*
* Copyright (C) 2018 Savoir-faire Linux Inc.
*
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "infohashtester.h"
// std
#include <iostream>
#include <string>
// opendht
#include "infohash.h"
namespace test {
CPPUNIT_TEST_SUITE_REGISTRATION(InfoHashTester);
void
InfoHashTester::setUp() {
}
void
InfoHashTester::testConstructors() {
// Default constructor creates a null infohash
auto nullHash = dht::InfoHash();
CPPUNIT_ASSERT(nullHash.size() == 20);
CPPUNIT_ASSERT(!nullHash);
// Build from a uint8_t. if length to short, should get a null infohash
uint8_t to_short[] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8};
auto infohash = dht::InfoHash(to_short, 8);
CPPUNIT_ASSERT(infohash.size() == 20);
CPPUNIT_ASSERT_EQUAL(infohash.toString(),
std::string("0000000000000000000000000000000000000000"));
// Build from a uint8_t. if length is enough, data should contains the uint8_t
uint8_t enough[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa,
0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa};
infohash = dht::InfoHash(enough, 20);
CPPUNIT_ASSERT(infohash.size() == 20);
const auto* data = infohash.data();
for (auto i = 0; i < 20; ++i) {
CPPUNIT_ASSERT_EQUAL(enough[i], data[i]);
}
// if too long, should be cutted to 20
uint8_t tooLong[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa,
0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb0};
infohash = dht::InfoHash(tooLong, 21);
CPPUNIT_ASSERT(infohash.size() == 20);
const auto* data2 = infohash.data();
for (auto i = 0; i < 20; ++i) {
CPPUNIT_ASSERT_EQUAL(enough[i], data2[i]);
}
// Build from string
auto infohashFromStr = dht::InfoHash("0102030405060708090A0102030405060708090A");
CPPUNIT_ASSERT(infohashFromStr.size() == 20);
const auto* dataStr = infohashFromStr.data();
for (auto i = 0; i < 20; ++i) {
CPPUNIT_ASSERT_EQUAL((int)dataStr[i], (int)data[i]);
}
}
void
InfoHashTester::testComperators() {
auto nullHash = dht::InfoHash();
auto minHash = dht::InfoHash("0000000000000000000000000000000000111110");
auto maxHash = dht::InfoHash("0111110000000000000000000000000000000000");
// operator ==
CPPUNIT_ASSERT_EQUAL(minHash, minHash);
CPPUNIT_ASSERT_EQUAL(minHash, dht::InfoHash("0000000000000000000000000000000000111110"));
CPPUNIT_ASSERT(!(minHash == maxHash));
// operator !=
CPPUNIT_ASSERT(!(minHash != minHash));
CPPUNIT_ASSERT(!(minHash != dht::InfoHash("0000000000000000000000000000000000111110")));
CPPUNIT_ASSERT(minHash != maxHash);
// operator<
CPPUNIT_ASSERT(nullHash < minHash);
CPPUNIT_ASSERT(nullHash < maxHash);
CPPUNIT_ASSERT(minHash < maxHash);
CPPUNIT_ASSERT(!(minHash < nullHash));
CPPUNIT_ASSERT(!(maxHash < nullHash));
CPPUNIT_ASSERT(!(maxHash < minHash));
CPPUNIT_ASSERT(!(minHash < minHash));
// bool()
CPPUNIT_ASSERT(maxHash);
CPPUNIT_ASSERT(!nullHash);
}
void
InfoHashTester::testLowBit() {
auto nullHash = dht::InfoHash();
auto minHash = dht::InfoHash("0000000000000000000000000000000000000010");
auto maxHash = dht::InfoHash("0100000000000000000000000000000000000000");
CPPUNIT_ASSERT_EQUAL(nullHash.lowbit(), -1);
CPPUNIT_ASSERT_EQUAL(minHash.lowbit(), 155);
CPPUNIT_ASSERT_EQUAL(maxHash.lowbit(), 7);
}
void
InfoHashTester::testCommonBits() {
auto nullHash = dht::InfoHash();
auto minHash = dht::InfoHash("0000000000000000000000000000000000000010");
auto maxHash = dht::InfoHash("0100000000000000000000000000000000000000");
CPPUNIT_ASSERT_EQUAL(dht::InfoHash::commonBits(nullHash, nullHash), (unsigned)160);
CPPUNIT_ASSERT_EQUAL(dht::InfoHash::commonBits(nullHash, minHash), (unsigned)155);
CPPUNIT_ASSERT_EQUAL(dht::InfoHash::commonBits(nullHash, maxHash), (unsigned)7);
CPPUNIT_ASSERT_EQUAL(dht::InfoHash::commonBits(minHash, maxHash), (unsigned)7);
}
void
InfoHashTester::testXorCmp() {
auto nullHash = dht::InfoHash();
auto minHash = dht::InfoHash("0000000000000000000000000000000000000010");
auto maxHash = dht::InfoHash("0100000000000000000000000000000000000000");
CPPUNIT_ASSERT_EQUAL(minHash.xorCmp(nullHash, maxHash), -1);
CPPUNIT_ASSERT_EQUAL(minHash.xorCmp(maxHash, nullHash), 1);
CPPUNIT_ASSERT_EQUAL(minHash.xorCmp(minHash, maxHash), -1);
CPPUNIT_ASSERT_EQUAL(minHash.xorCmp(maxHash, minHash), 1);
CPPUNIT_ASSERT_EQUAL(nullHash.xorCmp(minHash, maxHash), -1);
CPPUNIT_ASSERT_EQUAL(nullHash.xorCmp(maxHash, minHash), 1);
// Because hashes are circular in distance.
CPPUNIT_ASSERT_EQUAL(maxHash.xorCmp(nullHash, minHash), -1);
CPPUNIT_ASSERT_EQUAL(maxHash.xorCmp(minHash, nullHash), 1);
}
void
InfoHashTester::tearDown() {
}
} // namespace test
/*
* Copyright (C) 2018 Savoir-faire Linux Inc.
*
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#pragma once
// cppunit
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
namespace test {
class InfoHashTester : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(InfoHashTester);
CPPUNIT_TEST(testConstructors);
CPPUNIT_TEST(testComperators);
CPPUNIT_TEST(testLowBit);
CPPUNIT_TEST(testCommonBits);
CPPUNIT_TEST(testXorCmp);
CPPUNIT_TEST_SUITE_END();
public:
/**
* Method automatically called before each test by CppUnit
*/
void setUp();
/**
* Method automatically called after each test CppUnit
*/
void tearDown();
/**
* Test the differents behaviors of constructors
*/
void testConstructors();
/**
* Test compare operators
*/
void testComperators();
/**
* Test lowbit method
*/
void testLowBit();
/**
* Test commonBits method
*/
void testCommonBits();
/**
* Test xorCmp operators
*/
void testXorCmp();
};
} // namespace test
/*
* Copyright (C) 2017-2018 Savoir-faire Linux Inc.
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/ui/text/TestRunner.h>
#include <cppunit/CompilerOutputter.h>
#include <iostream>
int main(int argc, char** argv) {
CppUnit::TestFactoryRegistry &registry = CppUnit::TestFactoryRegistry::getRegistry();
CppUnit::Test *suite = registry.makeTest();
if (suite->countTestCases() == 0) {
std::cout << "No test cases specified for suite" << std::endl;
return 1;
}
CppUnit::TextUi::TestRunner runner;
runner.addTest(suite);
auto result = runner.run() ? 0 : 1;
return result;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment