Add build system, basic docs and crypto helpers module
Change-Id: I761cde5adac85596c5a3a53ec3e94a9a81fb5416
diff --git a/.jenkins.d/00-deps.sh b/.jenkins.d/00-deps.sh
new file mode 100755
index 0000000..d4d9c33
--- /dev/null
+++ b/.jenkins.d/00-deps.sh
@@ -0,0 +1,34 @@
+#!/usr/bin/env bash
+set -ex
+
+if has OSX $NODE_LABELS; then
+ FORMULAE=(boost openssl pkg-config)
+ if has OSX-10.13 $NODE_LABELS || has OSX-10.14 $NODE_LABELS; then
+ FORMULAE+=(python)
+ fi
+
+ if [[ -n $TRAVIS ]]; then
+ # Travis images come with a large number of pre-installed
+ # brew packages, don't waste time upgrading all of them
+ brew list --versions "${FORMULAE[@]}" || brew update
+ for FORMULA in "${FORMULAE[@]}"; do
+ brew list --versions "$FORMULA" || brew install "$FORMULA"
+ done
+ # Ensure /usr/local/opt/openssl exists
+ brew reinstall openssl
+ else
+ brew update
+ brew upgrade
+ brew install "${FORMULAE[@]}"
+ brew cleanup
+ fi
+
+elif has Ubuntu $NODE_LABELS; then
+ sudo apt-get -qq update
+ sudo apt-get -qy install g++ pkg-config python3-minimal \
+ libboost-all-dev libssl-dev libsqlite3-dev
+
+ if [[ $JOB_NAME == *"code-coverage" ]]; then
+ sudo apt-get -qy install gcovr lcov
+ fi
+fi
diff --git a/.jenkins.d/01-ndn-cxx.sh b/.jenkins.d/01-ndn-cxx.sh
new file mode 100755
index 0000000..7bf1cfe
--- /dev/null
+++ b/.jenkins.d/01-ndn-cxx.sh
@@ -0,0 +1,59 @@
+#!/usr/bin/env bash
+set -ex
+
+pushd "$CACHE_DIR" >/dev/null
+
+INSTALLED_VERSION=
+if has OSX $NODE_LABELS; then
+ BOOST=$(brew ls --versions boost)
+ OLD_BOOST=$(cat boost.txt || :)
+ if [[ $OLD_BOOST != $BOOST ]]; then
+ echo "$BOOST" > boost.txt
+ INSTALLED_VERSION=NONE
+ fi
+fi
+
+if [[ -z $INSTALLED_VERSION ]]; then
+ INSTALLED_VERSION=$(git -C ndn-cxx rev-parse HEAD 2>/dev/null || echo NONE)
+fi
+
+sudo rm -rf ndn-cxx-latest
+git clone --depth 1 https://github.com/named-data/ndn-cxx.git ndn-cxx-latest
+LATEST_VERSION=$(git -C ndn-cxx-latest rev-parse HEAD 2>/dev/null || echo UNKNOWN)
+
+if [[ $INSTALLED_VERSION != $LATEST_VERSION ]]; then
+ sudo rm -rf ndn-cxx
+ mv ndn-cxx-latest ndn-cxx
+else
+ sudo rm -rf ndn-cxx-latest
+fi
+
+sudo rm -f /usr/local/bin/ndnsec*
+sudo rm -fr /usr/local/include/ndn-cxx
+sudo rm -f /usr/local/lib{,64}/libndn-cxx*
+sudo rm -f /usr/local/lib{,64}/pkgconfig/libndn-cxx.pc
+
+pushd ndn-cxx >/dev/null
+
+if has Linux $NODE_LABELS && [[ $CXX != clang* && -z $DISABLE_ASAN ]]; then
+ # https://stackoverflow.com/a/47022141
+ ASAN="--with-sanitizer=address"
+fi
+if has CentOS-8 $NODE_LABELS; then
+ # https://bugzilla.redhat.com/show_bug.cgi?id=1721553
+ PCH="--without-pch"
+fi
+
+./waf --color=yes configure --disable-static --enable-shared --without-osx-keychain $ASAN $PCH
+./waf --color=yes build -j$WAF_JOBS
+sudo_preserve_env PATH -- ./waf --color=yes install
+
+popd >/dev/null
+popd >/dev/null
+
+if has CentOS-8 $NODE_LABELS; then
+ sudo tee /etc/ld.so.conf.d/ndn.conf >/dev/null <<< /usr/local/lib64
+fi
+if has Linux $NODE_LABELS; then
+ sudo ldconfig
+fi
diff --git a/.jenkins.d/10-build.sh b/.jenkins.d/10-build.sh
new file mode 100755
index 0000000..20e6bd1
--- /dev/null
+++ b/.jenkins.d/10-build.sh
@@ -0,0 +1,41 @@
+#!/usr/bin/env bash
+set -ex
+
+git submodule sync
+git submodule update --init
+
+if [[ -z $DISABLE_ASAN ]]; then
+ ASAN="--with-sanitizer=address"
+fi
+if [[ $JOB_NAME == *"code-coverage" ]]; then
+ COVERAGE="--with-coverage"
+fi
+
+if [[ $JOB_NAME != *"code-coverage" && $JOB_NAME != *"limited-build" ]]; then
+ # Build in release mode with tests
+ ./waf --color=yes configure --with-tests
+ ./waf --color=yes build -j$WAF_JOBS
+
+ # Cleanup
+ ./waf --color=yes distclean
+
+ # Build in release mode without tests
+ ./waf --color=yes configure
+ ./waf --color=yes build -j$WAF_JOBS
+
+ # Cleanup
+ ./waf --color=yes distclean
+fi
+
+# Build in debug mode with tests
+./waf --color=yes configure --debug --with-tests $ASAN $COVERAGE
+./waf --color=yes build -j$WAF_JOBS
+
+# (tests will be run against the debug version)
+
+# Install
+sudo_preserve_env PATH -- ./waf --color=yes install
+
+if has Linux $NODE_LABELS; then
+ sudo ldconfig
+fi
diff --git a/.jenkins.d/20-tests.sh b/.jenkins.d/20-tests.sh
new file mode 100755
index 0000000..226c77d
--- /dev/null
+++ b/.jenkins.d/20-tests.sh
@@ -0,0 +1,36 @@
+#!/usr/bin/env bash
+set -ex
+
+# Prepare environment
+rm -rf ~/.ndn
+
+BOOST_VERSION=$(python3 -c "import sys; sys.path.append('build/c4che'); import _cache; print(_cache.BOOST_VERSION_NUMBER);")
+
+ut_log_args() {
+ if (( BOOST_VERSION >= 106200 )); then
+ echo --logger=HRF,test_suite,stdout:XML,all,build/xunit-${1:-report}.xml
+ else
+ if [[ -n $XUNIT ]]; then
+ echo --log_level=all $( (( BOOST_VERSION >= 106000 )) && echo -- ) \
+ --log_format2=XML --log_sink2=build/xunit-${1:-report}.xml
+ else
+ echo --log_level=test_suite
+ fi
+ fi
+}
+
+# https://github.com/google/sanitizers/wiki/AddressSanitizerFlags
+ASAN_OPTIONS="color=always"
+ASAN_OPTIONS+=":check_initialization_order=1"
+ASAN_OPTIONS+=":detect_stack_use_after_return=1"
+ASAN_OPTIONS+=":strict_init_order=1"
+ASAN_OPTIONS+=":strict_string_checks=1"
+ASAN_OPTIONS+=":detect_invalid_pointer_pairs=2"
+ASAN_OPTIONS+=":strip_path_prefix=${PWD}/"
+export ASAN_OPTIONS
+
+export BOOST_TEST_BUILD_INFO=1
+export BOOST_TEST_COLOR_OUTPUT=1
+
+# Run unit tests
+./build/unit-tests $(ut_log_args)
diff --git a/.jenkins.d/30-coverage.sh b/.jenkins.d/30-coverage.sh
new file mode 100755
index 0000000..4cce87d
--- /dev/null
+++ b/.jenkins.d/30-coverage.sh
@@ -0,0 +1,30 @@
+#!/usr/bin/env bash
+set -ex
+
+if [[ $JOB_NAME == *"code-coverage" ]]; then
+ gcovr --object-directory=build \
+ --output=build/coverage.xml \
+ --exclude="$PWD/tests" \
+ --root=. \
+ --xml
+
+ # Generate also a detailed HTML output, but using lcov (better results)
+ lcov --quiet \
+ --capture \
+ --directory . \
+ --no-external \
+ --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 --branch-coverage \
+ --demangle-cpp \
+ --legend \
+ --output-directory build/coverage \
+ --title "ndncert unit tests" \
+ build/coverage.info
+fi
diff --git a/.jenkins.d/README.md b/.jenkins.d/README.md
new file mode 100644
index 0000000..e8dbf37
--- /dev/null
+++ b/.jenkins.d/README.md
@@ -0,0 +1,28 @@
+# CONTINUOUS INTEGRATION SCRIPTS
+
+## Environment Variables Used in Build Scripts
+
+- `NODE_LABELS`: space-separated list of platform properties. The included values are used by
+ the build scripts to select the proper behavior for different operating systems and versions.
+
+ The list should normally contain `[OS_TYPE]`, `[DISTRO_TYPE]`, and `[DISTRO_VERSION]`.
+
+ Example values:
+
+ - `[OS_TYPE]`: `Linux`, `OSX`
+ - `[DISTRO_TYPE]`: `Ubuntu`, `CentOS`
+ - `[DISTRO_VERSION]`: `Ubuntu-16.04`, `Ubuntu-18.04`, `CentOS-8`, `OSX-10.14`, `OSX-10.15`
+
+- `JOB_NAME`: optional variable that defines the type of build job. Depending on the job type,
+ the build scripts can perform different tasks.
+
+ Possible values:
+
+ - empty: default build task
+ - `code-coverage`: debug build with tests and code coverage analysis (Ubuntu Linux is assumed)
+ - `limited-build`: only a single debug build with tests
+
+- `CACHE_DIR`: directory containing cached files from previous builds, e.g., a compiled version
+ of ndn-cxx. If not set, `/tmp` is used.
+
+- `WAF_JOBS`: number of parallel build threads used by waf, defaults to 1.
diff --git a/.jenkins.d/util.sh b/.jenkins.d/util.sh
new file mode 100644
index 0000000..8077a74
--- /dev/null
+++ b/.jenkins.d/util.sh
@@ -0,0 +1,39 @@
+has() {
+ local saved_xtrace
+ [[ $- == *x* ]] && saved_xtrace=-x || saved_xtrace=+x
+ set +x
+
+ local p=$1
+ shift
+ local i ret=1
+ for i in "$@"; do
+ if [[ "${i}" == "${p}" ]]; then
+ ret=0
+ break
+ fi
+ done
+
+ set ${saved_xtrace}
+ return ${ret}
+}
+export -f has
+
+sudo_preserve_env() {
+ local saved_xtrace
+ [[ $- == *x* ]] && saved_xtrace=-x || saved_xtrace=+x
+ set +x
+
+ local vars=()
+ while [[ $# -gt 0 ]]; do
+ local arg=$1
+ shift
+ case ${arg} in
+ --) break ;;
+ *) vars+=("${arg}=${!arg}") ;;
+ esac
+ done
+
+ set ${saved_xtrace}
+ sudo env "${vars[@]}" "$@"
+}
+export -f sudo_preserve_env