diff --git a/.gitignore b/.gitignore index 85f028949e..59d45208ac 100644 --- a/.gitignore +++ b/.gitignore @@ -130,6 +130,11 @@ locale/*/*.flag .libs/ svn_version.h +## code coverage +*.gcov +*.gcno +*.gcda + # list of executables apps/1sec apps/concat diff --git a/.travis.yml b/.travis.yml index 627bcc4259..7c15dcac4c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -63,6 +63,7 @@ matrix: before_install: - if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then ( sudo apt-get -qq update ) fi - if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then ( sudo apt-get install -y freeglut3-dev libxmu-dev libxi-dev libfcgi-dev libxss-dev libnotify-dev libxcb-util0-dev libsqlite3-dev libgtk2.0-dev libwebkitgtk-dev mingw-w64 binutils-mingw-w64-i686 binutils-mingw-w64-x86-64 gcc-mingw-w64 gcc-mingw-w64-i686 gcc-mingw-w64-x86-64 g++-mingw-w64 g++-mingw-w64-i686 g++-mingw-w64-x86-64 realpath p7zip-full ) fi + - if [[ "${TRAVIS_OS_NAME}" == "linux" && "${BOINC_TYPE}" == "unit-test" ]]; then ( sudo pip install codecov ) fi - if [[ "${BOINC_TYPE}" == "integration-test" ]]; then ( sudo apt-get install ansible/trusty-backports; sudo service mysql stop; ) fi before_script: @@ -80,7 +81,7 @@ script: - if [[ "${BOINC_TYPE}" == "apps-mingw" ]]; then ( cd lib && MINGW=x86_64-w64-mingw32 make -f Makefile.mingw wrapper ) fi - if [[ "${BOINC_TYPE}" == "manager-osx" ]]; then ( ./3rdParty/buildMacDependencies.sh -q && ./mac_build/buildMacBOINC-CI.sh --no_shared_headers ) fi - if [[ "${BOINC_TYPE}" == "manager-android" ]]; then ( cd android && ./buildAndroidBOINC-CI.sh --arch arm --silent && ./buildAndroidBOINC-CI.sh --arch arm64 --silent && ./buildAndroidBOINC-CI.sh --arch x86 --silent && ./buildAndroidBOINC-CI.sh --arch x86_64 --silent && cd BOINC && ./gradlew assemble -w && cd ../../ ) fi -- if [[ "${BOINC_TYPE}" == "unit-test" ]]; then ( /bin/true ) fi +- if [[ "${BOINC_TYPE}" == "unit-test" ]]; then ( ./3rdParty/buildLinuxDependencies.sh --gtest-only && ./configure --disable-client --disable-manager --enable-unit-tests CFLAGS="-g -O0" CXXFLAGS="-g -O0" && make && ./tests/executeUnitTests.sh --report-coverage ) fi - if [[ "${BOINC_TYPE}" == "integration-test" ]]; then ( ./integration_test/executeTestSuite.sh ) fi after_success: diff --git a/3rdParty/buildGoogletestLinux.sh b/3rdParty/buildGoogletestLinux.sh new file mode 100644 index 0000000000..ccd69d8177 --- /dev/null +++ b/3rdParty/buildGoogletestLinux.sh @@ -0,0 +1,67 @@ +#!/bin/bash + +# This file is part of BOINC. +# http://boinc.berkeley.edu +# Copyright (C) 2019 University of California +# +# BOINC is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# +# BOINC 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 Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with BOINC. If not, see . + +# Script to build a googletest library for BOINC + +# Usage: +# cd [path]/googletest-release-1.8.1/ +# source path_to_this_script [--clean] [--prefix PATH] +# +# the --clean argument will force a full rebuild. +# if --prefix is given as absolute path the library is installed into there + +doclean="" +debug_flag="" +lprefix="" +cmdline_prefix="" +while [[ $# -gt 0 ]]; do + key="$1" + case $key in + -clean|--clean) + doclean="yes" + ;; + -prefix|--prefix) + lprefix="$2" + cmdline_prefix="--prefix=${lprefix}" + shift + ;; + esac + shift # past argument or value +done + +cd googletest +autoreconf -i -f +if [ $? -ne 0 ]; then cd ..; return 1; fi +./configure "${cmdline_prefix}" +if [ $? -ne 0 ]; then cd ..; return 1; fi +if [ "${doclean}" = "yes" ]; then + make clean +fi +make +if [ $? -ne 0 ]; then cd ..; return 1; fi + +# make install is not supported so copy files manually +if [ "x${lprefix}" != "x" ]; then + mkdir -p ${lprefix}/lib ${lprefix}/include ${lprefix}/bin + (cp -r lib/.libs/*.a ${lprefix}/lib && cp -r include/gtest ${lprefix}/include && cp scripts/gtest-config ${lprefix}/bin) + if [ $? -ne 0 ]; then cd ..; return 1; fi +fi + +cd .. +return 0 diff --git a/3rdParty/buildLinuxDependencies.sh b/3rdParty/buildLinuxDependencies.sh index 5115394e7c..baca1549db 100755 --- a/3rdParty/buildLinuxDependencies.sh +++ b/3rdParty/buildLinuxDependencies.sh @@ -2,7 +2,7 @@ # This file is part of BOINC. # http://boinc.berkeley.edu -# Copyright (C) 2017 University of California +# Copyright (C) 2019 University of California # # BOINC is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License @@ -51,6 +51,7 @@ ROOTDIR=$(pwd) cache_dir="" doclean="" wxoption="" +gtest_only="" build_config="Release" while [[ $# -gt 0 ]]; do key="$1" @@ -69,6 +70,9 @@ while [[ $# -gt 0 ]]; do --disable-webview) wxoption="--disable-webview ${wxoption} " ;; + --gtest-only) + gtest_only="yes" + ;; *) echo "unrecognized option $key" ;; @@ -134,7 +138,11 @@ if [ "${doclean}" = "yes" ]; then fi #download_and_build $DIRNAME $FILENAME $DOWNLOADURL $BUILDSCRIPT -download_and_build "wxWidgets-3.0.2" "wxWidgets-3.0.2.tar.bz2" "https://sourceforge.net/projects/wxwindows/files/3.0.2/wxWidgets-3.0.2.tar.bz2" "${ROOTDIR}/3rdParty/buildWxLinux.sh ${wxoption}" +if [ "${gtest_only}" = "yes" ]; then + download_and_build "googletest-release-1.8.1" "release-1.8.1.tar.gz" "https://github.com/google/googletest/archive/release-1.8.1.tar.gz" "${ROOTDIR}/3rdParty/buildGoogletestLinux.sh" +else + download_and_build "wxWidgets-3.0.2" "wxWidgets-3.0.2.tar.bz2" "https://sourceforge.net/projects/wxwindows/files/3.0.2/wxWidgets-3.0.2.tar.bz2" "${ROOTDIR}/3rdParty/buildWxLinux.sh ${wxoption}" +fi # change back to root directory cd ${ROOTDIR} || exit 1 diff --git a/Makefile.am b/Makefile.am index 1627f1bd1c..a06839ba46 100644 --- a/Makefile.am +++ b/Makefile.am @@ -71,7 +71,7 @@ svn_version.h: generate_svn_version.sh # Add a stage target for staging a distribution clean-generic: - rm -rf stage + rm -rf stage *.gcov stage: all if [ ! -d stage ] ; then mkdir stage ; fi diff --git a/configure.ac b/configure.ac index bc8733d4b3..9b9c754656 100644 --- a/configure.ac +++ b/configure.ac @@ -126,6 +126,12 @@ AC_ARG_ENABLE(apps, [enable_apps=${enableval}], [enable_apps=no]) +AC_ARG_ENABLE(unit-tests, + AS_HELP_STRING([--enable-unit-tests], + [enable building the boinc unit tests]), + [enable_unit_tests=${enableval}], + [enable_unit_tests=no]) + AC_ARG_ENABLE(pkg-libs, AS_HELP_STRING([--enable-pkg-libs], [Builds and installs components that would be present in a @@ -139,8 +145,9 @@ AC_ARG_ENABLE(pkg-libs, enable_manager=no enable_install_headers=no enable_static=no - enable_boinczip=yes - enable_apps=no + enable_boinczip=yes + enable_apps=no + enable_unit_tests=no ], []) @@ -156,8 +163,9 @@ AC_ARG_ENABLE(pkg-devel, enable_client=no enable_manager=no enable_install_headers=yes - enable_boinczip=yes - enable_apps=no + enable_boinczip=yes + enable_apps=no + enable_unit_tests=no ], []) @@ -173,8 +181,9 @@ AC_ARG_ENABLE(pkg-client, enable_client=yes enable_manager=no enable_install_headers=no - enable_boinczip=no - enable_apps=no + enable_boinczip=no + enable_apps=no + enable_unit_tests=no ], []) @@ -188,8 +197,9 @@ AC_ARG_ENABLE(pkg-manager, enable_client=no enable_manager=yes enable_install_headers=no - enable_boinczip=no - enable_apps=no + enable_boinczip=no + enable_apps=no + enable_unit_tests=no ], []) @@ -213,6 +223,9 @@ fi if test x$enable_apps = xyes ; then configured_to_build="${configured_to_build} apps" fi +if test x$enable_unit_tests = xyes ; then + configured_to_build="${configured_to_build} unit-tests" +fi if test -z "${configured_to_build}" ; then AC_MSG_ERROR([ @@ -1049,6 +1062,7 @@ AM_CONDITIONAL(ENABLE_MANAGER, [ test "x${ac_cv_have_wxwidgets}" = xyes -a "${en AM_CONDITIONAL(ENABLE_LIBRARIES, [test "${enable_libraries}" = yes]) AM_CONDITIONAL(ENABLE_BOINCZIP, [test "${enable_boinczip}" = yes]) AM_CONDITIONAL(ENABLE_APPS, [test "${enable_apps}" = yes]) +AM_CONDITIONAL(ENABLE_UNIT_TESTS, [test "${enable_unit_tests}" = yes]) AM_CONDITIONAL(ENABLE_BOINCCRYPT, [test "x${enable_server}" = xyes || test "x${enable_client}" = xyes ]) AM_CONDITIONAL(INSTALL_HEADERS, [test "${enable_install_headers}" = yes]) AM_CONDITIONAL(HAVE_CUDA_LIB, [test "${enable_client}" = yes -a -f ./coprocs/CUDA/posix/${boinc_platform}/libcudart.so]) diff --git a/lib/Makefile.am b/lib/Makefile.am index 245dd599b5..c9f29552c8 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -244,7 +244,7 @@ $(LIBBOINC_FCGI_STATIC): libboinc_fcgi.la $(LN) .libs/$(LIBBOINC_FCGI_STATIC) . clean: clean-am - rm -f $(LIBBOINC_STATIC) $(LIBBOINC_CRYPT_STATIC) $(LIBBOINC_FCGI_STATIC) + rm -f $(LIBBOINC_STATIC) $(LIBBOINC_CRYPT_STATIC) $(LIBBOINC_FCGI_STATIC) *.gcno *.gcda *.gcov endif # end of "if ENABLE_LIBRARIES" diff --git a/m4/boinc_set_compile_flags.m4 b/m4/boinc_set_compile_flags.m4 index 1e2e0cef73..97f0677e06 100644 --- a/m4/boinc_set_compile_flags.m4 +++ b/m4/boinc_set_compile_flags.m4 @@ -117,4 +117,11 @@ if test x${enable_generic_processor} = xyes ; then ;; esac fi + +if test x${enable_unit_tests} = xyes ; then + BOINC_CHECK_CFLAG(--coverage) + BOINC_CHECK_CXXFLAG(--coverage) + LDFLAGS="$LDFLAGS --coverage" +fi + ]) diff --git a/sched/Makefile.am b/sched/Makefile.am index c43dfd96d6..ba01358b48 100644 --- a/sched/Makefile.am +++ b/sched/Makefile.am @@ -334,4 +334,4 @@ PHONY-start: status stop: PHONY-start @test -f $@ || @LN_S@ start $@ && test -f $@ -CLEANFILES = status stop +CLEANFILES = status stop *.gcno *.gcda *.gcov diff --git a/tests/executeUnitTests.sh b/tests/executeUnitTests.sh new file mode 100755 index 0000000000..555b31abde --- /dev/null +++ b/tests/executeUnitTests.sh @@ -0,0 +1,79 @@ +#!/bin/bash + +# This file is part of BOINC. +# http://boinc.berkeley.edu +# Copyright (C) 2019 University of California +# +# BOINC is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# +# BOINC 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 Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with BOINC. If not, see . + +# Script to execute googletest based unit tests for BOINC + +# Usage: +# ./tests/executeUnitTests.sh [--report-coverage] +# +# if --report-coverage is given the test coverage will be reported to codecov.io + +# check working directory because the script needs to be called like: ./tests/executeUnitTests.sh +if [ ! -d "tests" ]; then + echo "start this script in the source root directory" + exit 1 +fi + +ROOTDIR=$(pwd) +CI_RUN="${TRAVIS:-false}" +report="" +while [[ $# -gt 0 ]]; do + key="$1" + case $key in + --report-coverage) + report="yes" + ;; + *) + echo "unrecognized option $key" + ;; + esac + shift # past argument or value +done + +command -v cmake >/dev/null 2>&1 || { echo >&2 "cmake is needed but not installed. Aborting."; exit 1; } + +if [ "${report}" = "yes" ]; then + command -v gcov >/dev/null 2>&1 || { echo >&2 "gcov (lcov) is needed but not installed. Aborting."; exit 1; } + command -v codecov >/dev/null 2>&1 || { echo >&2 "codecov (pip install codecov) is needed but not installed. Aborting."; exit 1; } +fi + +cd tests || exit 1 +if [ -d "gtest" ]; then + rm -rf gtest + if [ $? -ne 0 ]; then cd ..; exit 1; fi +fi +mkdir gtest +if [ $? -ne 0 ]; then cd ..; exit 1; fi +cd gtest +cmake ../unit-tests +if [ $? -ne 0 ]; then cd ../..; exit 1; fi +make +if [ $? -ne 0 ]; then cd ../..; exit 1; fi + +for T in lib sched; do + [ -d "${T}" ] && ./${T}/test_${T}; +done + +cd ../.. +if [ "${report}" = "yes" ]; then + for T in lib sched; do + [ -d "${T}" ] && gcov -lp *.o >/dev/null; + done + codecov -X gcov +fi diff --git a/tests/unit-tests/CMakeLists.txt b/tests/unit-tests/CMakeLists.txt new file mode 100644 index 0000000000..766632a116 --- /dev/null +++ b/tests/unit-tests/CMakeLists.txt @@ -0,0 +1,37 @@ +cmake_minimum_required(VERSION 2.8) + +project(BOINC_unit_testing) +enable_testing() + +set (CMAKE_CXX_STANDARD 11) +set (CMAKE_CXX_FLAGS "-g -Wall -Wextra -Werror --coverage") + + +find_package(Threads REQUIRED) + +# There is no easy way to interface with the autotools driven build system in boinc +# so the paths below are hardcoded and are mainly suited for building on Travis CI +# TODO: make paths configurable and generate them from boinc make or switch boinc to cmake + +include_directories(BEFORE "${PROJECT_SOURCE_DIR}/../../3rdParty/buildCache/linux/include") +include_directories("${PROJECT_SOURCE_DIR}/../..") +include_directories("${PROJECT_SOURCE_DIR}/../../sched") +include_directories("${PROJECT_SOURCE_DIR}/../../db") +include_directories("${PROJECT_SOURCE_DIR}/../../lib") +include_directories("${PROJECT_SOURCE_DIR}/../../tools") +include_directories("/usr/include/mariadb") +include_directories("/usr/include/mariadb/mysql") + + +find_library(GTEST_MAIN_LIB libgtest_main.a PATHS ${PROJECT_SOURCE_DIR}/../../3rdParty/buildCache/linux/lib NO_DEFAULT_PATH) +message(STATUS "gtest_main_lib: ${GTEST_MAIN_LIB}") +find_library(GTEST_LIB gtest PATHS ${PROJECT_SOURCE_DIR}/../../3rdParty/buildCache/linux/lib NO_DEFAULT_PATH) +message(STATUS "gtest_lib: ${GTEST_LIB}") +find_library(SCHED_LIB libsched.a PATHS ${PROJECT_SOURCE_DIR}/../../sched NO_DEFAULT_PATH) +find_library(BOINC_CRYPT_LIB libboinc_crypt.a PATHS ${PROJECT_SOURCE_DIR}/../../lib NO_DEFAULT_PATH) +find_library(BOINC_LIB libboinc.a PATHS ${PROJECT_SOURCE_DIR}/../../lib NO_DEFAULT_PATH) +find_library(MYSQL_LIB NAMES mariadb mysql) +message(STATUS "mysql_lib: ${MYSQL_LIB}") + +add_subdirectory(lib) +add_subdirectory(sched) diff --git a/tests/unit-tests/lib/CMakeLists.txt b/tests/unit-tests/lib/CMakeLists.txt new file mode 100644 index 0000000000..d681555765 --- /dev/null +++ b/tests/unit-tests/lib/CMakeLists.txt @@ -0,0 +1,7 @@ +file(GLOB SRCS *.cpp) + +add_executable(test_lib ${SRCS}) + +TARGET_LINK_LIBRARIES(test_lib "${GTEST_LIB}" "${SCHED_LIB}" "${BOINC_CRYPT_LIB}" "${BOINC_LIB}" "${GTEST_MAIN_LIB}" pthread) + +add_test(NAME test_lib COMMAND test_lib) diff --git a/tests/unit-tests/lib/test_str_util.cpp b/tests/unit-tests/lib/test_str_util.cpp new file mode 100644 index 0000000000..3069408576 --- /dev/null +++ b/tests/unit-tests/lib/test_str_util.cpp @@ -0,0 +1,96 @@ +#include "gtest/gtest.h" +#include "common_defs.h" +#include "str_util.h" +#include +#include + +namespace test_str_util { + + // The fixture for testing class Foo. + + class test_str_util : public ::testing::Test { + protected: + // You can remove any or all of the following functions if its body + // is empty. + + test_str_util() { + // You can do set-up work for each test here. + } + + virtual ~test_str_util() { + // You can do clean-up work that doesn't throw exceptions here. + } + + // If the constructor and destructor are not enough for setting up + // and cleaning up each test, you can define the following methods: + + virtual void SetUp() { + // Code here will be called immediately after the constructor (right + // before each test). + } + + virtual void TearDown() { + // Code here will be called immediately after each test (right + // before the destructor). + } + + // Objects declared here can be used by all tests in the test case for Foo. + }; + + // Tests that Foo does Xyz. + + TEST_F(test_str_util, path_to_filename) { + std::string fname = ""; + ASSERT_EQ(path_to_filename("/home/blah", fname), 0); + ASSERT_EQ(fname, "blah"); + ASSERT_EQ(path_to_filename("hellokeith", fname), 0); + ASSERT_EQ(fname, "hellokeith"); + fname = ""; + ASSERT_EQ(path_to_filename("/home/blah/", fname), -2); + ASSERT_EQ(fname, ""); + ASSERT_EQ(path_to_filename("", fname), -1); + ASSERT_EQ(fname, ""); + } + + TEST_F(test_str_util, nbytes_to_string) { + char buf[256]; + nbytes_to_string(1024, 0, buf, sizeof (buf)); + ASSERT_STREQ(buf, "1.00 KB"); + nbytes_to_string(1024, 1024 * 1024, buf, sizeof (buf)); + ASSERT_STREQ(buf, "0.00/1.00 MB"); + nbytes_to_string(512, 1024, buf, sizeof (buf)); + ASSERT_STREQ(buf, "0.50/1.00 KB"); + nbytes_to_string(50000000000000, 0, buf, sizeof (buf)); + ASSERT_STREQ(buf, "45.47 TB"); + } + + TEST_F(test_str_util, strip_whitespace) { + std::string tmp = " white space "; + strip_whitespace(tmp); + ASSERT_EQ(tmp, "white space"); + tmp = "nospaces"; + strip_whitespace(tmp); + ASSERT_EQ(tmp, "nospaces"); + } + + TEST_F(test_str_util, collapse_whitespace) { + std::string tmp = " white space "; + collapse_whitespace(tmp); + ASSERT_EQ(tmp, " white space "); + tmp = "nospaces"; + collapse_whitespace(tmp); + ASSERT_EQ(tmp, "nospaces"); + tmp = "inner spaces"; + collapse_whitespace(tmp); + ASSERT_EQ(tmp, "inner spaces"); + } + + TEST_F(test_str_util, is_valid_filename) { + //char tmp = "filename.txt"; + bool ret = is_valid_filename("filename.txt"); + ASSERT_TRUE(ret); + ret = is_valid_filename("../filename.txt"); + ASSERT_FALSE(ret); + } + +} // namespace diff --git a/tests/unit-tests/lib/test_url.cpp b/tests/unit-tests/lib/test_url.cpp new file mode 100644 index 0000000000..43c87b4fb2 --- /dev/null +++ b/tests/unit-tests/lib/test_url.cpp @@ -0,0 +1,49 @@ +#include "gtest/gtest.h" +#include "common_defs.h" +#include "url.h" +#include +#include + +namespace test_url { + + // The fixture for testing class Foo. + + class test_url : public ::testing::Test { + protected: + // You can remove any or all of the following functions if its body + // is empty. + + test_url() { + // You can do set-up work for each test here. + } + + virtual ~test_url() { + // You can do clean-up work that doesn't throw exceptions here. + } + + // If the constructor and destructor are not enough for setting up + // and cleaning up each test, you can define the following methods: + + virtual void SetUp() { + // Code here will be called immediately after the constructor (right + // before each test). + } + + virtual void TearDown() { + // Code here will be called immediately after each test (right + // before the destructor). + } + + // Objects declared here can be used by all tests in the test case for Foo. + }; + + // Tests that Foo does Xyz. + + TEST_F(test_url, is_https) { + ASSERT_EQ(is_https("hello"), false); + ASSERT_EQ(is_https("https://www.google.com"), true); + ASSERT_EQ(is_https("http://www.google.com"), false); + ASSERT_EQ(is_https("xhttps://www.google.com"), false); + } + +} // namespace diff --git a/tests/unit-tests/sched/CMakeLists.txt b/tests/unit-tests/sched/CMakeLists.txt new file mode 100644 index 0000000000..bb15e0376d --- /dev/null +++ b/tests/unit-tests/sched/CMakeLists.txt @@ -0,0 +1,9 @@ +file(GLOB SRCS *.cpp) + +add_executable(test_sched ${SRCS}) + +TARGET_COMPILE_OPTIONS(test_sched PUBLIC ${MYSQL_CFLAGS}) + +TARGET_LINK_LIBRARIES(test_sched "${GTEST_LIB}" "${SCHED_LIB}" "${BOINC_CRYPT_LIB}" "${BOINC_LIB}" ${MYSQL_LIB} "${GTEST_MAIN_LIB}" pthread) + +add_test(NAME test_sched COMMAND test_sched) diff --git a/tests/unit-tests/sched/test_credit.cpp b/tests/unit-tests/sched/test_credit.cpp new file mode 100644 index 0000000000..677cd71b24 --- /dev/null +++ b/tests/unit-tests/sched/test_credit.cpp @@ -0,0 +1,50 @@ +#include "gtest/gtest.h" +#include "common_defs.h" +#include "credit.h" + +namespace test_credit { + + // The fixture for testing class Foo. + + class test_credit : public ::testing::Test { + protected: + // You can remove any or all of the following functions if its body + // is empty. + + test_credit() { + // You can do set-up work for each test here. + } + + virtual ~test_credit() { + // You can do clean-up work that doesn't throw exceptions here. + } + + // If the constructor and destructor are not enough for setting up + // and cleaning up each test, you can define the following methods: + + virtual void SetUp() { + // Code here will be called immediately after the constructor (right + // before each test). + } + + virtual void TearDown() { + // Code here will be called immediately after each test (right + // before the destructor). + } + + // Objects declared here can be used by all tests in the test case for Foo. + }; + + // Tests that Foo does Xyz. + + TEST_F(test_credit, fpops_to_credit) { + ASSERT_EQ(fpops_to_credit(1.0), COBBLESTONE_SCALE); + ASSERT_NE(fpops_to_credit(5.0), COBBLESTONE_SCALE); + ASSERT_EQ(fpops_to_credit(6000000.0), 6000000.0 * COBBLESTONE_SCALE); + } + + TEST_F(test_credit, cpu_time_to_credit) { + ASSERT_EQ(cpu_time_to_credit(1.0, 1.0), COBBLESTONE_SCALE); + } + +} // namespace