build+ci: add code coverage support

This commit also adds GlobalConfigurationFixture to ensure that running
unit tests doesn't interact with system configuration (e.g., doesn't use
or alter user certificates).

Change-Id: I621ce14425a777c94d41b8132cd2858d91235b4d
Refs: #3808
This commit is contained in:
Eric Newberry authored and Alexander Afanasyev committed 2017-01-18 17:37:05 -08:00
1 parent bf1c069b7f
commit 716ab60f05
5 files changed
+130 -5

No files matched your search

+1 -1
View File
@@ -27,7 +27,7 @@ fi
# Configure/build in debug mode with tests
if [[ $JOB_NAME == *"code-coverage" ]]; then
COVERAGE="" # TODO add code coverage support
COVERAGE="--with-coverage"
elif ! has OSX-10.9 $NODE_LABELS && ! has OSX-10.11 $NODE_LABELS; then
ASAN="--with-sanitizer=address"
fi
+19 -3
View File
@@ -6,11 +6,27 @@ source "$JDIR"/util.sh
set -x
# TODO add code coverage support
if false && [[ $JOB_NAME == *"code-coverage" ]]; then
if [[ $JOB_NAME == *"code-coverage" ]]; then
gcovr --object-directory=build \
--output=build/coverage.xml \
--filter="$PWD/(core|tools)" \
--exclude="$PWD/tests" \
--root=. \
--xml
# Generate also a detailed HTML output, but using lcov (better results)
lcov --quiet \
--capture --no-external \
--directory . \
--rc lcov_branch_coverage=1 \
--output-file build/coverage-with-tests.info
lcov --quiet \
--remove build/coverage-with-tests.info "$PWD/tests/*" \
--rc lcov_branch_coverage=1 \
--output-file build/coverage.info
genhtml --legend \
--rc genhtml_branch_coverage=1 \
build/coverage.info \
--output-directory build/coverage
fi
+22
View File
@@ -0,0 +1,22 @@
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
from waflib import TaskGen, Logs
def options(opt):
opt.add_option('--with-coverage', action='store_true', default=False, dest='with_coverage',
help='''Set compiler flags for gcc to enable code coverage information''')
def configure(conf):
if conf.options.with_coverage:
if not conf.options.debug:
conf.fatal("Code coverage flags require debug mode compilation (add --debug)")
conf.check_cxx(cxxflags=['-fprofile-arcs', '-ftest-coverage', '-fPIC'],
linkflags=['-fprofile-arcs'], uselib_store='GCOV', mandatory=True)
@TaskGen.feature('cxx','cc')
@TaskGen.after('process_source')
def add_coverage(self):
if getattr(self, 'use', ''):
self.use += ' GCOV'
else:
self.use = 'GCOV'
+83
View File
@@ -0,0 +1,83 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2017, Regents of the University of California.
*
* This file is part of ndn-tools (Named Data Networking Essential Tools).
* See AUTHORS.md for complete list of ndn-tools authors and contributors.
*
* ndn-tools 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.
*
* ndn-tools 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
* ndn-tools, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#include <boost/version.hpp>
#include <boost/filesystem.hpp>
#include "test-common.hpp"
namespace ndn {
namespace tools {
namespace tests {
class GlobalConfigurationFixture : boost::noncopyable
{
public:
GlobalConfigurationFixture()
{
if (getenv("HOME") != nullptr) {
m_home = getenv("HOME");
}
if (getenv("NDN_CLIENT_PIB") != nullptr) {
m_pib = getenv("NDN_CLIENT_PIB");
}
if (getenv("NDN_CLIENT_TPM") != nullptr) {
m_tpm = getenv("NDN_CLIENT_TPM");
}
boost::filesystem::path dir(TMP_TESTS_PATH);
dir /= "test-home";
setenv("HOME", dir.generic_string().c_str(), 1);
if (exists(dir)) {
remove_all(dir);
}
setenv("NDN_CLIENT_PIB", ("pib-sqlite3:" + dir.string()).c_str(), 1);
setenv("NDN_CLIENT_TPM", ("tpm-file:" + dir.string()).c_str(), 1);
create_directories(dir);
}
~GlobalConfigurationFixture()
{
if (!m_home.empty()) {
setenv("HOME", m_home.c_str(), 1);
}
if (!m_pib.empty()) {
setenv("NDN_CLIENT_PIB", m_pib.c_str(), 1);
}
if (!m_tpm.empty()) {
setenv("NDN_CLIENT_TPM", m_tpm.c_str(), 1);
}
}
private:
std::string m_home;
std::string m_pib;
std::string m_tpm;
};
BOOST_GLOBAL_FIXTURE(GlobalConfigurationFixture)
#if (BOOST_VERSION >= 105900)
;
#endif // BOOST_VERSION >= 105900
} // namespace tests
} // namespace tools
} // namespace ndn
+5 -1
View File
@@ -9,7 +9,8 @@ import os
def options(opt):
opt.load(['compiler_cxx', 'gnu_dirs'])
opt.load(['default-compiler-flags', 'sanitizers', 'sphinx_build', 'boost'],
opt.load(['default-compiler-flags', 'coverage', 'sanitizers', 'boost',
'sphinx_build'],
tooldir=['.waf-tools'])
opt.add_option('--with-tests', action='store_true', default=False,
@@ -33,6 +34,9 @@ def configure(conf):
boost_libs += ' unit_test_framework'
conf.check_boost(lib=boost_libs)
# Loading "late" to prevent tests from being compiled with profiling flags
conf.load('coverage')
conf.recurse('tools')
conf.load('sanitizers')