57 Commits

Author SHA1 Message Date
Davide Pesavento 9fa8ac31dc ci: add build testing against named-data PPA
Change-Id: Ifaed697f9b2b51bd561e735a6b399c8d54e71071
2023-11-25 21:48:07 -05:00
Davide Pesavento d45f888b9a Switch to Face::getIoContext()
Change-Id: I6c5242ead4dc6d5d37c0fa77c3e68a55d60a87bc
2023-11-11 17:32:23 -05:00
Davide Pesavento 1af7949d1b build: require boost >= 1.71.0
Refs: #5276
Change-Id: I287a52dab0212d1ce0da77afb563554214cac68a
2023-09-22 15:45:21 -04:00
Davide Pesavento 9330c2ee49 build: more accurate Boost lib dependencies
See also named-data/ndn-cxx@5686c51b87

Change-Id: I33cfbf95ed267c6a549a934185bcb610c0c34a80
2023-09-14 21:38:02 -04:00
Davide Pesavento 9f100b3fb1 build: update waf to version 2.0.26
Change-Id: I0f901f1c05376194fcc2595e9d081ca5739471c2
2023-08-19 02:02:24 -04:00
Davide Pesavento 97741e796d build: sync default build flags with ndn-cxx
Change-Id: I0610ade8e117eeedb53d40de1658444ac3e9f561
2023-08-12 16:36:07 -04:00
Davide Pesavento 48dbab6de8 tests: follow DummyClientFace namespace change
Change-Id: Ia2ca95d8621e264747b299d1ecd5405bca0dd5af
2023-08-12 16:06:52 -04:00
Davide Pesavento ebc0275572 tests: fix compilation with latest ndn-cxx
Change-Id: I32579dd584efee508c862b3d5f2f1bdad7487bab
2023-05-09 15:37:05 -04:00
Davide Pesavento ed77870ccc build: align minimum build requirements with ndn-cxx
Change-Id: I3aac15aa09e9dbd8ad666fe91e4a536a152ee0df
2023-04-26 15:31:31 -04:00
Davide Pesavento 2ff10561bd build: switch source archive to xz compression
Mention gerrit in the README

Change-Id: I468cedde1a15f760aef00ac2995dd5f73728b89e
2023-02-19 20:14:06 -05:00
Davide Pesavento 85601037ef ci: adopt reusable workflows from named-data/actions
Change-Id: I4219458d27723ee7c408a665f7b31a1ca557b1e0
2023-02-14 13:38:03 -05:00
Davide Pesavento 3fb27eb32e Prepare release 0.5.5
Change-Id: I508eff35ad01271b48cbc86519eaceb7e11f0435
2022-12-31 14:00:51 -05:00
Davide Pesavento 535b51d6fe build: update waf to version 2.0.24
Change-Id: Ib4c2354d8eb4372a5f6f34c81b1f626fa5988466
2022-12-02 17:20:54 -05:00
Davide Pesavento cda4489045 build: link with lld by default on Linux; add Xcode 14.1 to CI matrix
Change-Id: Ie14db81bec544e7b502c17d46d19f206ae0bbd52
2022-11-15 13:40:33 -05:00
Davide Pesavento 044ecc93c6 docs: restore exception handling in conf.py
Change-Id: I3f114ad2934e84fb664a63e0dd0ad1641569c721
2022-09-25 03:10:03 -04:00
Davide Pesavento 55492d5a14 docs: simplify conf.py and fix compatibility with upcoming Sphinx 6.0
Change-Id: I970c5691cb4b1879854023a3747c2bf63189c128
2022-09-19 18:38:02 -04:00
Davide Pesavento 15a7442759 build+ci: support macOS on arm64
This commit also syncs the CI config and scripts with ndn-cxx

Change-Id: I9866345393e2354e65a0082c047e846b2f8641f5
2022-08-19 15:48:45 -04:00
Davide Pesavento 9c4bd6d711 build: support CentOS Stream 9, make graphviz optional
Change-Id: I5c0d824720f9f701ee2a88774e661c7472baea88
2022-07-26 15:28:08 -04:00
Davide Pesavento 54bf15afef Update C++ badge in README.md
Change-Id: I776fbdf1438b68ef8eb35ab00fa0015209b89c9c
2022-07-26 03:23:32 -04:00
Davide Pesavento 8663ed1c21 build: migrate to C++17
Change-Id: Ic5c01274f62556764ea96fc232cf3d835c4ab659
2022-07-23 13:51:24 -04:00
Davide Pesavento 5a6292db4e build: explicitly require libndn-cxx >= 0.8.0
Change-Id: I029ded8120e149e945a74feaf58739960dbfa3f2
2022-03-12 15:26:16 -05:00
Davide Pesavento 5f5101adc3 Avoid deprecated ndn-cxx functions
Also, waf is updated to version 2.0.23

Change-Id: I053d7dce733455ec352931a1614082542ca00570
2022-03-11 20:05:03 -05:00
Davide Pesavento 26a0326dc5 build: align minimum build dependencies with ndn-cxx
* gcc 7.4
 * clang 6.0
 * Xcode 10.0 (11.3 or later recommended)

Change-Id: Ie867798d37898dbabb0620de719fff4bd46df590
2022-03-07 13:37:34 -05:00
Davide Pesavento 44ec20773e Drop redundant calls to Interest::setCanBePrefix(false)
Change-Id: I319ec178e3bb27c0dd77318d0cb201850a1e7126
2022-03-07 13:32:04 -05:00
Davide Pesavento 22eeb2914f ci: replace Travis with GitHub Actions
Sync docs/conf.py with ndn-cxx

Change-Id: I2c7106ef52a0e7c00de6767c6b59dbd3ce1dc082
2021-10-02 04:13:24 -04:00
Davide Pesavento ad7a61b745 ci: don't use deprecated ndnsec commands
Change-Id: I8f9976fb990471c1ab883635568c6fd2df6a3ef8
2021-06-04 13:40:03 -04:00
Philipp Moll 96b9a1d5fd docs: Deprecated note in README.md
Change-Id: I510c090670ff18b7534d58ece6866d0bc589686c
2021-02-27 06:44:39 +01:00
Davide Pesavento dbac16ad65 Prepare release 0.5.4
Change-Id: Ie87fa94ed401a8552632c0d861a70bdda228e634
2021-02-18 20:55:43 -05:00
Davide Pesavento 780e646ff5 ci: compile-check installed headers
Script copied from ndn-cxx with minor modifications

Also, move tlv.hpp to detail/ and cleanup includes in common.hpp

Change-Id: I6240601f005c61bb3547bd5acf854200f3b13093
2021-02-10 13:43:26 -05:00
Davide Pesavento 07684bced7 Move config.hpp and a few more private headers to a 'detail' subdir
Also upgrade waf to version 2.0.21

Change-Id: Id290b8336c607fb3939f2ab96dd066dae9810c1e
2021-02-07 20:09:28 -05:00
Davide Pesavento e7dc77695c Replace all uses of BOOST_THROW_EXCEPTION with NDN_THROW
Refs: #4834
Change-Id: I99a5c3665735f245e943506893faade3954cae5e
2020-12-23 01:05:53 -05:00
Davide Pesavento 5f408ae7f5 build: align minimum build dependencies with ndn-cxx
* Recommend gcc >= 7.4.0
 * Require clang >= 4.0, or Xcode >= 9.0 on macOS
 * Silence an ABI-related diagnostic message from gcc on armv7
 * Update Travis CI job matrix

Refs: #5087, #5106
Change-Id: I71aef00147a7ad93b537904bb309745fed77f509
2020-07-21 16:35:35 -04:00
Alexander Afanasyev cc6f67cec9 Adjust includes for the updated locations of ndn-cxx security headers
Change-Id: I3f7c9823881552114a6e9c9182c2d06b7742f552
2020-06-06 16:16:36 -04:00
Alexander Afanasyev 675d6fb210 Rename VERSION to VERSION.info to avoid conflicts with modern STL
On case-insensitive file systems (e.g., macOS), inclusion of the new
standard <version> header resulted in unexpected inclusion of VERSION
file.

Change-Id: I7f8dd4703c76e833797135b980bbcc6c2e97bcef
2020-06-01 18:55:17 -04:00
Davide Pesavento dbee9bf49a ci: update Travis configuration
* Add testing on arm64, ppc64le, and s390x with select compiler versions
   (s390x is allowed to fail due to bug #5098)
 * Drop all versions of gcc < 7 and clang < 5
 * Add clang 11 (development branch)
 * Reenable ASan on Linux with clang 7, the upstream bug has been fixed
 * Drop Xcode 9.2 (macOS 10.12 is no longer supported)
 * Upgrade Xcode 11 to 11.3

Change-Id: I87c5c76ee4fd7295c4bd5ffce6a30076e0d0143e
2020-04-02 16:23:05 -04:00
Davide Pesavento d6a0956c35 logic: fix -Wrange-loop-construct warning with clang 10
Change-Id: Ia4cd193e099b9e85da48f83087cd93482db9a628
2020-04-02 02:48:46 -04:00
Davide Pesavento a0546dbc86 build+ci: switch to python3
Also in this commit:
 * Sync CI scripts with other projects
 * Modernize docs/conf.py
 * Cleanup README.md
 * Use the official markdown version of the GPLv3

Refs: #5095
Change-Id: Ie607fcde1f6e41fa5efbbb41b21cb08583017442
2020-04-01 21:19:45 -04:00
Eric Newberry e3fe048411 docs: restructure and update AUTHORS.md
refs #5078

Change-Id: I69e84ca2aeee4f049171d332ed545a851edf24b1
2020-02-04 15:12:13 -08:00
Davide Pesavento e275292728 build: upgrade waf to version 2.0.19
Change-Id: I5ca28fd7cfd26988952fccb275c5ce925e94bbb8
2020-01-23 23:40:02 -05:00
Davide Pesavento 27416441b3 logic: remove some leftover code
Change-Id: I6e98ac216ce49f078e59c55efd856ce8e03d0b71
2020-01-23 23:10:24 -05:00
Davide Pesavento dd000762d6 Prepare release 0.5.3
Change-Id: I2c9ca578746cdbadebacaed10ad175923d31a5aa
2020-01-15 01:34:33 -05:00
Davide Pesavento c47774fd95 build: pass pkg_config_path to check_cfg() when looking for libndn-cxx
Instead of modifying os.environ.

This commit also updates some waf tools and fixes the value of
includedir in the generated .pc file.

Refs: #5042
Change-Id: Idf0481f36664cc085571265747a004655001c0ed
2019-11-10 18:39:08 -05:00
Ashlesh Gawande a1ad604672 src: schedule sync interest on NoRoute NACK
refs #5012

Change-Id: I671b507c66e1957aae976c859e81591c93dc4d94
2019-10-08 16:34:24 -05:00
Davide Pesavento dfd704aa4e ci: upgrade Travis config to Ubuntu 18.04
Also in this commit:

 * Drop clang 3.8 (no easy way to install it on 18.04)
 * Add clang 10 (trunk)
 * Drop Xcode 8.3
 * Upgrade Xcode 10.2 to 10.3
 * Add Xcode 11

Change-Id: Ic8fd05fdacdfc190c722244372a8852705762f32
2019-09-26 00:52:33 -04:00
Davide Pesavento d7de2d45b2 logic: initialize m_syncReset before using it
This commit also disables sending the reset interest upon
initialization of the Logic to preserve the previous behavior, where a
meaningless interest was sent out as a result of a bug.

Change-Id: Iec35d7745a0be06e768d4ae5f6afb8d867e590fc
2019-08-13 10:51:44 -04:00
Davide Pesavento 4db56c8e3f ci: add gcc-9 to Travis CI build matrix
Change-Id: I37c8399650666a4682fda4229c3ded2dca8e5ebd
2019-06-23 19:42:05 -04:00
Davide Pesavento d057cf1969 Follow ndn::Scheduler API changes
Refs: #4883
Change-Id: I71e39f13f62302248d13825481d06d10f694cd94
2019-03-20 23:38:40 -04:00
Davide Pesavento 5c39ba1b6e ci: enable LeakSanitizer
Change-Id: If9472204a11cef3e4b4e743ac08d7a0ecf173ef6
2019-03-20 01:08:00 -04:00
Davide Pesavento 5188f31d50 ci: update .travis.yml and jenkins scripts
Change-Id: I22034ef33a13910e2a5639deec4a5609b5a6ad99
2019-03-18 19:22:12 -04:00
Davide Pesavento 0d837e3f2a ndn::util::scheduler => ndn::scheduler
Refs: #4883
Change-Id: I4049fdd424b6037b754b0d0a0e740667b82298e6
2019-03-17 15:04:42 -04:00
Junxiao Shi c490212fb2 logic: use ScopedEventId
refs #4698

Change-Id: Ic5b4cd3327a690693eb416be31c25ed95516ab99
2019-02-12 07:33:21 -08:00
Junxiao Shi 8e4e76d3ff logic+socket: use PendingInterestHandle and RegisteredPrefixHandle
refs #4316, #3919

Change-Id: I0ddde90dddd235535faab6a27e67c57d0767aa07
2019-02-08 15:25:08 -07:00
Davide Pesavento fae9def359 build: various updates
* Upgrade waf to 2.0.14
 * Sync default compiler flags with ndn-cxx
 * Simplify compilation of unit-tests

Change-Id: I94865d405240c181dd4cfdd1cb730b756ad5166a
2019-01-30 10:37:24 -05:00
Ashlesh Gawande 9a306fe0a9 logic: use properly seeded rng via ndn::random::getRandomNumberEngine
Change-Id: I2a3a84b62ef9b21857097ce6a56fed92f8ddea86
2019-01-14 16:52:29 -06:00
Alexander Afanasyev e19f3f6b5a Prepare release 0.5.2
Change-Id: I32adf57b09e27107b87f293bb785d6f67db4b558
2018-10-17 08:00:15 -07:00
Ashlesh Gawande 1d1092d356 Transition to v0.3 format
Set CanBePrefix on interests
Remove remaining exclude filter logic

refs: #4691, #4684

Change-Id: I6d1b23ba9973f5b54ba49e5122b18ac0d9f88720
2018-08-05 11:04:15 -05:00
Davide Pesavento 4a9395bb6e build: require gcc >= 5.3 and switch to C++14
Change-Id: Ifb805ced42e9f8aedce473c1fe91f68b27acefec
Refs: #3076, #4462
2018-06-06 16:28:16 -04:00
68 changed files with 1571 additions and 2477 deletions
+16
View File
@@ -0,0 +1,16 @@
name: CI
on:
push:
workflow_dispatch:
permissions: {}
jobs:
Ubuntu:
uses: named-data/actions/.github/workflows/jenkins-script-ubuntu.yml@v1
macOS:
uses: named-data/actions/.github/workflows/jenkins-script-macos.yml@v1
PPA:
uses: named-data/actions/.github/workflows/ppa.yml@v1
with:
extra-deps: libboost-iostreams-dev
+10
View File
@@ -0,0 +1,10 @@
name: Docs
on:
push:
workflow_dispatch:
permissions: {}
jobs:
html:
uses: named-data/actions/.github/workflows/docs-html.yml@v1
+1 -1
View File
@@ -26,4 +26,4 @@ __pycache__/
*.py[cod]
# Other
/VERSION
/VERSION.info
+46 -4
View File
@@ -1,10 +1,52 @@
#!/usr/bin/env bash
set -e
set -eo pipefail
DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
case $(uname) in
Linux)
if [[ -e /etc/os-release ]]; then
source /etc/os-release
else
source /usr/lib/os-release
fi
export ID VERSION_ID
export ID_LIKE="${ID} ${ID_LIKE} linux"
export PATH="${HOME}/.local/bin${PATH:+:}${PATH}"
;;
Darwin)
# Emulate a subset of os-release(5)
export ID=macos
export VERSION_ID=$(sw_vers -productVersion)
export PATH="/usr/local/bin${PATH:+:}${PATH}"
if [[ -x /opt/homebrew/bin/brew ]]; then
eval "$(/opt/homebrew/bin/brew shellenv)"
elif [[ -x /usr/local/bin/brew ]]; then
eval "$(/usr/local/bin/brew shellenv)"
fi
;;
esac
for file in "$DIR"/.jenkins.d/*; do
export CACHE_DIR=${CACHE_DIR:-/tmp}
if [[ $JOB_NAME == *"code-coverage" ]]; then
export DISABLE_ASAN=yes
export DISABLE_HEADERS_CHECK=yes
fi
# https://reproducible-builds.org/docs/source-date-epoch/
export SOURCE_DATE_EPOCH=$(git log -1 --format=%ct)
for file in .jenkins.d/*; do
[[ -f $file && -x $file ]] || continue
echo "Run: $file"
if [[ -n $GITHUB_ACTIONS ]]; then
label=$(basename "$file" | sed -E 's/[[:digit:]]+-(.*)\..*/\1/')
echo "::group::${label}"
fi
echo "\$ $file"
"$file"
if [[ -n $GITHUB_ACTIONS ]]; then
echo "::endgroup::"
fi
done
+29 -20
View File
@@ -1,29 +1,38 @@
#!/usr/bin/env bash
set -e
set -eo pipefail
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
source "$JDIR"/util.sh
APT_PKGS=(build-essential pkg-config python3-minimal
libboost-all-dev libssl-dev libsqlite3-dev)
FORMULAE=(boost openssl pkg-config)
PIP_PKGS=()
case $JOB_NAME in
*code-coverage)
APT_PKGS+=(lcov python3-pip)
PIP_PKGS+=('gcovr~=5.2')
;;
*Docs)
APT_PKGS+=(doxygen graphviz python3-pip)
FORMULAE+=(doxygen graphviz)
PIP_PKGS+=(sphinx sphinxcontrib-doxylink)
;;
esac
set -x
if has OSX $NODE_LABELS; then
FORMULAE=(boost openssl pkg-config)
brew update
if [[ -n $TRAVIS ]]; then
# travis images come with a large number of brew packages
# pre-installed, don't waste time upgrading all of them
for FORMULA in "${FORMULAE[@]}"; do
brew outdated $FORMULA || brew upgrade $FORMULA
done
else
brew upgrade
if [[ $ID == macos ]]; then
if [[ -n $GITHUB_ACTIONS ]]; then
export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1
fi
brew install "${FORMULAE[@]}"
brew cleanup
brew update
brew install --formula "${FORMULAE[@]}"
elif [[ $ID_LIKE == *debian* ]]; then
sudo apt-get -qq update
sudo apt-get -qy install "${APT_PKGS[@]}"
elif [[ $ID_LIKE == *fedora* ]]; then
sudo dnf -y install gcc-c++ libasan lld pkgconf-pkg-config python3 \
boost-devel openssl-devel sqlite-devel
fi
if has Ubuntu $NODE_LABELS; then
sudo apt-get -qq update
sudo apt-get -qy install build-essential pkg-config libboost-all-dev \
libsqlite3-dev libssl-dev
if (( ${#PIP_PKGS[@]} )); then
pip3 install --user --upgrade --upgrade-strategy=eager "${PIP_PKGS[@]}"
fi
+18 -24
View File
@@ -1,16 +1,11 @@
#!/usr/bin/env bash
set -e
set -exo pipefail
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
source "$JDIR"/util.sh
set -x
pushd "${CACHE_DIR:-/tmp}" >/dev/null
pushd "$CACHE_DIR" >/dev/null
INSTALLED_VERSION=
if has OSX $NODE_LABELS; then
BOOST=$(brew ls --versions boost)
if [[ $ID == macos ]]; then
BOOST=$(brew list --formula --versions boost)
OLD_BOOST=$(cat boost.txt || :)
if [[ $OLD_BOOST != $BOOST ]]; then
echo "$BOOST" > boost.txt
@@ -22,35 +17,34 @@ 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 git://github.com/named-data/ndn-cxx ndn-cxx-latest
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
sudo rm -rf ndn-cxx
mv ndn-cxx-latest ndn-cxx
else
sudo rm -Rf ndn-cxx-latest
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/libndn-cxx*
sudo rm -f /usr/local/lib/pkgconfig/libndn-cxx.pc
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
./waf configure --color=yes --enable-shared --disable-static --without-osx-keychain
./waf build --color=yes -j${WAF_JOBS:-1}
sudo env "PATH=$PATH" ./waf install --color=yes
./waf --color=yes configure --without-osx-keychain
./waf --color=yes build
sudo ./waf --color=yes install
popd >/dev/null
popd >/dev/null
if has Linux $NODE_LABELS; then
sudo ldconfig
elif has FreeBSD10 $NODE_LABELS; then
sudo ldconfig -m
if [[ $ID_LIKE == *fedora* ]]; then
sudo tee /etc/ld.so.conf.d/ndn.conf >/dev/null <<< /usr/local/lib64
fi
if [[ $ID_LIKE == *linux* ]]; then
sudo ldconfig
fi
+8
View File
@@ -0,0 +1,8 @@
#!/usr/bin/env bash
set -exo pipefail
PROJ=ChronoSync
sudo rm -fr /usr/local/include/"$PROJ"
sudo rm -f /usr/local/lib{,64}/lib"$PROJ"*
sudo rm -f /usr/local/lib{,64}/pkgconfig/{,lib}"$PROJ".pc
+27 -30
View File
@@ -1,46 +1,43 @@
#!/usr/bin/env bash
set -e
set -eo pipefail
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
source "$JDIR"/util.sh
if [[ -z $DISABLE_ASAN ]]; then
ASAN="--with-sanitizer=address"
fi
if [[ $JOB_NAME == *"code-coverage" ]]; then
COVERAGE="--with-coverage"
fi
set -x
# Cleanup
sudo env "PATH=$PATH" ./waf --color=yes distclean
if [[ $JOB_NAME != *"code-coverage" && $JOB_NAME != *"limited-build" ]]; then
# Configure/build in optimized mode with tests
./waf --color=yes configure --with-tests
./waf --color=yes build -j${WAF_JOBS:-1}
# Build in release mode with tests
./waf --color=yes configure --with-tests
./waf --color=yes build
# Cleanup
sudo env "PATH=$PATH" ./waf --color=yes distclean
# Cleanup
./waf --color=yes distclean
# Configure/build in optimized mode without tests
./waf --color=yes configure
./waf --color=yes build -j${WAF_JOBS:-1}
# Build in release mode without tests
./waf --color=yes configure
./waf --color=yes build
# Cleanup
sudo env "PATH=$PATH" ./waf --color=yes distclean
# Cleanup
./waf --color=yes distclean
fi
# Configure/build in debug mode with tests
if [[ $JOB_NAME == *"code-coverage" ]]; then
COVERAGE="--with-coverage"
elif [[ -n $BUILD_WITH_ASAN || -z $TRAVIS ]]; then
ASAN="--with-sanitizer=address"
fi
./waf --color=yes configure --debug --with-tests $COVERAGE $ASAN
./waf --color=yes build -j${WAF_JOBS:-1}
# Build in debug mode with tests
./waf --color=yes configure --debug --with-tests $ASAN $COVERAGE
./waf --color=yes build
# (tests will be run against debug version)
# (tests will be run against the debug version)
# Install
sudo env "PATH=$PATH" ./waf --color=yes install
sudo ./waf --color=yes install
if has Linux $NODE_LABELS; then
sudo ldconfig
elif has FreeBSD $NODE_LABELS; then
sudo ldconfig -a
if [[ $ID_LIKE == *fedora* ]]; then
sudo tee /etc/ld.so.conf.d/ndn.conf >/dev/null <<< /usr/local/lib64
fi
if [[ $ID_LIKE == *linux* ]]; then
sudo ldconfig
fi
+18 -40
View File
@@ -1,48 +1,26 @@
#!/usr/bin/env bash
set -e
set -eo pipefail
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
source "$JDIR"/util.sh
# 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
# https://www.boost.org/doc/libs/release/libs/test/doc/html/boost_test/runtime_config/summary.html
export BOOST_TEST_BUILD_INFO=1
export BOOST_TEST_COLOR_OUTPUT=1
export BOOST_TEST_DETECT_MEMORY_LEAK=0
export BOOST_TEST_LOGGER=HRF,test_suite,stdout:XML,all,build/xunit-log.xml
set -x
# Prepare environment
rm -Rf ~/.ndn
if has OSX $NODE_LABELS; then
security unlock-keychain -p named-data
fi
ndnsec-keygen "/tmp/jenkins/$NODE_NAME" | ndnsec-install-cert -
BOOST_VERSION=$(python -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
}
ASAN_OPTIONS="color=always"
ASAN_OPTIONS+=":detect_leaks=false"
ASAN_OPTIONS+=":detect_stack_use_after_return=true"
ASAN_OPTIONS+=":check_initialization_order=true"
ASAN_OPTIONS+=":strict_init_order=true"
ASAN_OPTIONS+=":detect_invalid_pointer_pairs=1"
ASAN_OPTIONS+=":detect_container_overflow=false"
ASAN_OPTIONS+=":strict_string_checks=true"
ASAN_OPTIONS+=":strip_path_prefix=${PWD}/"
export ASAN_OPTIONS
export BOOST_TEST_COLOR_OUTPUT="yes"
export NDN_LOG="*=DEBUG"
rm -rf ~/.ndn
# Run unit tests
./build/unit-tests $(ut_log_args)
./build/unit-tests
+43
View File
@@ -0,0 +1,43 @@
#!/usr/bin/env bash
set -eo pipefail
# It's intentional not to use `set -x`, because this script explicitly prints useful information
# and should not run in trace mode.
PROJ=ChronoSync
PCFILE=ChronoSync
if [[ -n $DISABLE_HEADERS_CHECK ]]; then
echo 'Skipping headers check.'
exit 0
fi
if [[ $ID_LIKE == *fedora* ]]; then
export PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig
fi
CXX=${CXX:-g++}
STD=-std=c++17
CXXFLAGS="-O2 -Wall -Wno-unneeded-internal-declaration -Wno-unused-const-variable $(pkg-config --cflags libndn-cxx $PCFILE)"
INCLUDEDIR="$(pkg-config --variable=includedir $PCFILE)"/$PROJ
echo "Using: $CXX $STD $CXXFLAGS"
NCHECKED=0
NERRORS=0
while IFS= read -r -d '' H; do
echo "Checking header ${H#${INCLUDEDIR}/}"
"$CXX" -xc++ $STD $CXXFLAGS -c -o /dev/null "$H" || : $((NERRORS++))
: $((NCHECKED++))
done < <(find "$INCLUDEDIR" -name '*.hpp' -type f -print0 2>/dev/null)
if [[ $NCHECKED -eq 0 ]]; then
echo "No headers found. Is $PROJ installed?"
exit 1
else
echo "$NCHECKED headers checked."
fi
if [[ $NERRORS -gt 0 ]]; then
echo "$NERRORS headers could not be compiled."
exit 1
fi
+24 -24
View File
@@ -1,36 +1,36 @@
CONTINUOUS INTEGRATION SCRIPTS
==============================
# Continuous Integration Scripts
Environment Variables Used in Build Scripts
-------------------------------------------
## Environment Variables
- `NODE_LABELS`: the variable defines a list of OS properties. The set values are used by the
build scripts to select proper behavior for different OS.
- `ID`: lower-case string that identifies the operating system, for example: `ID=ubuntu`,
`ID=centos`. See [os-release(5)] for more information. On macOS, where `os-release` is
not available, we emulate it by setting `ID=macos`.
The list should include at least `[OS_TYPE]`, `[DISTRO_TYPE]`, and `[DISTRO_VERSION]`.
- `ID_LIKE`: space-separated list of operating system identifiers that are closely related
to the running OS. See [os-release(5)] for more information. The listed values are used
by the CI scripts to select the proper behavior for different platforms and OS flavors.
Possible values for Linux:
Examples:
* `[OS_TYPE]`: `Linux`
* `[DISTRO_TYPE]`: `Ubuntu`
* `[DISTRO_VERSION]`: `Ubuntu-14.04`, `Ubuntu-16.04`
- On CentOS, `ID_LIKE="centos rhel fedora linux"`
- On Ubuntu, `ID_LIKE="ubuntu debian linux"`
Possible values for OS X / macOS:
- `VERSION_ID`: identifies the operating system version, excluding any release code names.
See [os-release(5)] for more information. Examples: `VERSION_ID=42`, `VERSION_ID=22.04`.
* `[OS_TYPE]`: `OSX`
* `[DISTRO_TYPE]`: `OSX` (can be absent)
* `[DISTRO_VERSION]`: `OSX-10.10`, `OSX-10.11`, `OSX-10.12`
- `JOB_NAME`: defines the type of the current CI job. Depending on the job type, the CI
scripts can perform different tasks.
- `JOB_NAME`: optional variable to define type of the job. Depending on the defined job type,
the build scripts can perform different tasks.
Supported values:
Possible values:
- empty: default build task
- `code-coverage`: debug build with tests and code coverage analysis
- `limited-build`: only a single debug build with tests
* empty: default build process
* `code-coverage` (Linux OS is assumed): debug build with tests and code coverage analysis
* `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.
- `CACHE_DIR`: the variable defines a path to folder containing cached files from previous builds,
e.g., a compiled version of ndn-cxx library. If not set, `/tmp` is used.
- `DISABLE_ASAN`: disable building with AddressSanitizer. This is automatically set for
the `code-coverage` job type.
- `WAF_JOBS`: number of parallel build jobs used by waf, defaults to 1.
[os-release(5)]: https://www.freedesktop.org/software/systemd/man/os-release.html
-18
View File
@@ -1,18 +0,0 @@
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}
}
+2
View File
@@ -0,0 +1,2 @@
<aa@cs.fiu.edu> <alexander.afanasyev@ucla.edu>
<davidepesa@gmail.com> <davide.pesavento@lip6.fr>
-159
View File
@@ -1,159 +0,0 @@
sudo: required
language: generic
env:
global:
- JOB_NAME=limited-build
- WAF_JOBS=2
matrix:
include:
# Linux/gcc
- os: linux
dist: trusty
env:
- CXX=g++-4.8
- NODE_LABELS="Linux Ubuntu Ubuntu-14.04"
- BUILD_WITH_ASAN=yes
- os: linux
dist: trusty
addons:
apt:
sources: ubuntu-toolchain-r-test
packages: g++-4.9
env:
- CXX=g++-4.9
- NODE_LABELS="Linux Ubuntu Ubuntu-14.04"
- BUILD_WITH_ASAN=yes
- os: linux
dist: trusty
addons:
apt:
sources: ubuntu-toolchain-r-test
packages: g++-5
env:
- CXX=g++-5
- NODE_LABELS="Linux Ubuntu Ubuntu-14.04"
- BUILD_WITH_ASAN=yes
- os: linux
dist: trusty
addons:
apt:
sources: ubuntu-toolchain-r-test
packages: g++-6
env:
- CXX=g++-6
- NODE_LABELS="Linux Ubuntu Ubuntu-14.04"
- BUILD_WITH_ASAN=yes
- os: linux
dist: trusty
addons:
apt:
sources: ubuntu-toolchain-r-test
packages: g++-7
env:
- CXX=g++-7
- NODE_LABELS="Linux Ubuntu Ubuntu-14.04"
- BUILD_WITH_ASAN=yes
# Linux/clang
- os: linux
dist: trusty
addons:
apt:
packages: clang-3.5
env:
- CXX=clang++-3.5
- NODE_LABELS="Linux Ubuntu Ubuntu-14.04"
- BUILD_WITH_ASAN=yes
- os: linux
dist: trusty
addons:
apt:
packages: clang-3.6
env:
- CXX=clang++-3.6
- NODE_LABELS="Linux Ubuntu Ubuntu-14.04"
- BUILD_WITH_ASAN=yes
- os: linux
dist: trusty
addons:
apt:
sources:
- llvm-toolchain-precise-3.7
- ubuntu-toolchain-r-test
packages: clang-3.7
env:
- CXX=clang++-3.7
- NODE_LABELS="Linux Ubuntu Ubuntu-14.04"
- os: linux
dist: trusty
addons:
apt:
sources:
- llvm-toolchain-precise-3.8
- ubuntu-toolchain-r-test
packages: clang-3.8
env:
- CXX=clang++-3.8
- NODE_LABELS="Linux Ubuntu Ubuntu-14.04"
- BUILD_WITH_ASAN=yes
- os: linux
dist: trusty
addons:
apt:
sources:
- llvm-toolchain-trusty-3.9
- ubuntu-toolchain-r-test
packages: clang-3.9
env:
- CXX=clang++-3.9
- NODE_LABELS="Linux Ubuntu Ubuntu-14.04"
- os: linux
dist: trusty
addons:
apt:
sources:
- llvm-toolchain-trusty-4.0
- ubuntu-toolchain-r-test
packages: clang-4.0
env:
- CXX=clang++-4.0
- NODE_LABELS="Linux Ubuntu Ubuntu-14.04"
- BUILD_WITH_ASAN=yes
- os: linux
dist: trusty
addons:
apt:
sources:
- llvm-toolchain-trusty-5.0
- ubuntu-toolchain-r-test
packages: clang-5.0
env:
- CXX=clang++-5.0
- NODE_LABELS="Linux Ubuntu Ubuntu-14.04"
- BUILD_WITH_ASAN=yes
# macOS/clang
# https://docs.travis-ci.com/user/osx-ci-environment/#OS-X-Version
- os: osx
osx_image: xcode7.3
env:
- NODE_LABELS="OSX OSX-10.11"
- BUILD_WITH_ASAN=yes
- os: osx
osx_image: xcode8.3
env:
- NODE_LABELS="OSX OSX-10.12"
- BUILD_WITH_ASAN=yes
- os: osx
osx_image: xcode9
env:
- NODE_LABELS="OSX OSX-10.12"
- BUILD_WITH_ASAN=yes
before_script:
- ${CXX:-c++} --version
- python --version
script:
- ./.jenkins
+53 -42
View File
@@ -54,8 +54,9 @@ from waflib import Utils, Logs, Errors
from waflib.Configure import conf
from waflib.TaskGen import feature, after_method
BOOST_LIBS = ['/usr/lib', '/usr/local/lib', '/opt/local/lib', '/sw/lib', '/lib']
BOOST_INCLUDES = ['/usr/include', '/usr/local/include', '/opt/local/include', '/sw/include']
BOOST_LIBS = ['/usr/lib', '/usr/local/lib', '/opt/homebrew/lib', '/opt/local/lib', '/sw/lib', '/lib']
BOOST_INCLUDES = ['/usr/include', '/usr/local/include', '/opt/homebrew/include', '/opt/local/include', '/sw/include']
BOOST_VERSION_FILE = 'boost/version.hpp'
BOOST_VERSION_CODE = '''
#include <iostream>
@@ -90,13 +91,18 @@ int main() { boost::thread t; }
BOOST_LOG_CODE = '''
#include <boost/log/trivial.hpp>
int main() { BOOST_LOG_TRIVIAL(info) << "boost_log is working"; }
'''
BOOST_LOG_SETUP_CODE = '''
#include <boost/log/trivial.hpp>
#include <boost/log/utility/setup/console.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
int main() {
using namespace boost::log;
add_common_attributes();
add_console_log(std::clog, keywords::format = "%Message%");
BOOST_LOG_TRIVIAL(debug) << "log is working" << std::endl;
BOOST_LOG_TRIVIAL(info) << "boost_log_setup is working";
}
'''
@@ -145,7 +151,7 @@ def options(opt):
opt.add_option('--boost-abi', type='string', default='', dest='boost_abi',
help='''select libraries with tags (gd for debug, static is automatically added),
see doc Boost, Getting Started, chapter 6.1''')
opt.add_option('--boost-linkage_autodetect', action="store_true", dest='boost_linkage_autodetect',
opt.add_option('--boost-linkage_autodetect', action='store_true', dest='boost_linkage_autodetect',
help="auto-detect boost linkage options (don't get used to it / might break other stuff)")
opt.add_option('--boost-toolset', type='string',
default='', dest='boost_toolset',
@@ -175,7 +181,7 @@ def boost_get_version(self, d):
try:
txt = node.read()
except EnvironmentError:
Logs.error("Could not read the file %r" % node.abspath())
Logs.error('Could not read the file %r' % node.abspath())
else:
re_but1 = re.compile('^#define\\s+BOOST_LIB_VERSION\\s+"(.+)"', re.M)
m1 = re_but1.search(txt)
@@ -183,7 +189,7 @@ def boost_get_version(self, d):
m2 = re_but2.search(txt)
if m1 and m2:
return (m1.group(1), m2.group(1))
return self.check_cxx(fragment=BOOST_VERSION_CODE, includes=[d], execute=True, define_ret=True).split(":")
return self.check_cxx(fragment=BOOST_VERSION_CODE, includes=[d], execute=True, define_ret=True).split(':')
@conf
def boost_get_includes(self, *k, **kw):
@@ -194,10 +200,10 @@ def boost_get_includes(self, *k, **kw):
if self.__boost_get_version_file(d):
return d
if includes:
self.end_msg('headers not found in %s' % includes)
self.end_msg('headers not found in %s' % includes, 'YELLOW')
self.fatal('The configuration failed')
else:
self.end_msg('headers not found, please provide a --boost-includes argument (see help)')
self.end_msg('headers not found, please provide a --boost-includes argument (see help)', 'YELLOW')
self.fatal('The configuration failed')
@@ -240,10 +246,10 @@ def __boost_get_libs_path(self, *k, **kw):
break
if not path:
if libs:
self.end_msg('libs not found in %s' % libs)
self.end_msg('libs not found in %s' % libs, 'YELLOW')
self.fatal('The configuration failed')
else:
self.end_msg('libs not found, please provide a --boost-libs argument (see help)')
self.end_msg('libs not found, please provide a --boost-libs argument (see help)', 'YELLOW')
self.fatal('The configuration failed')
self.to_log('Found the boost path in %r with the libraries:' % path)
@@ -313,7 +319,7 @@ def boost_get_libs(self, *k, **kw):
libs.append(format_lib_name(file.name))
break
else:
self.end_msg('lib %s not found in %s' % (lib, path.abspath()))
self.end_msg('lib %s not found in %s' % (lib, path.abspath()), 'YELLOW')
self.fatal('The configuration failed')
return libs
@@ -354,7 +360,7 @@ def _check_pthread_flag(self, *k, **kw):
# ... -mt is also the pthreads flag for HP/aCC
# -lpthread: GNU Linux, etc.
# --thread-safe: KAI C++
if Utils.unversioned_sys_platform() == "sunos":
if Utils.unversioned_sys_platform() == 'sunos':
# On Solaris (at least, for some versions), libc contains stubbed
# (non-functional) versions of the pthreads routines, so link-based
# tests will erroneously succeed. (We need to link with -pthreads/-mt/
@@ -362,23 +368,22 @@ def _check_pthread_flag(self, *k, **kw):
# a function called by this macro, so we could check for that, but
# who knows whether they'll stub that too in a future libc.) So,
# we'll just look for -pthreads and -lpthread first:
boost_pthread_flags = ["-pthreads", "-lpthread", "-mt", "-pthread"]
boost_pthread_flags = ['-pthreads', '-lpthread', '-mt', '-pthread']
else:
boost_pthread_flags = ["", "-lpthreads", "-Kthread", "-kthread", "-llthread", "-pthread",
"-pthreads", "-mthreads", "-lpthread", "--thread-safe", "-mt"]
boost_pthread_flags = ['', '-lpthreads', '-Kthread', '-kthread', '-llthread', '-pthread',
'-pthreads', '-mthreads', '-lpthread', '--thread-safe', '-mt']
for boost_pthread_flag in boost_pthread_flags:
try:
self.env.stash()
self.env['CXXFLAGS_%s' % var] += [boost_pthread_flag]
self.env['LINKFLAGS_%s' % var] += [boost_pthread_flag]
self.check_cxx(code=PTHREAD_CODE, msg=None, use=var, execute=False)
self.check_cxx(code=PTHREAD_CODE, msg=None, use=var, execute=False, quiet=True)
self.end_msg(boost_pthread_flag)
return
except self.errors.ConfigurationError:
self.env.revert()
self.end_msg('None')
self.end_msg('none')
@conf
def check_boost(self, *k, **kw):
@@ -403,21 +408,24 @@ def check_boost(self, *k, **kw):
var = kw.get('uselib_store', 'BOOST')
self.find_program('dpkg-architecture', var='DPKG_ARCHITECTURE', mandatory=False)
if self.env.DPKG_ARCHITECTURE:
deb_host_multiarch = Utils.subprocess.check_output([self.env.DPKG_ARCHITECTURE[0], '-qDEB_HOST_MULTIARCH']).strip()
BOOST_LIBS.insert(0, '/usr/lib/%s' % deb_host_multiarch)
if not self.env.DONE_FIND_BOOST_COMMON:
self.find_program('dpkg-architecture', var='DPKG_ARCHITECTURE', mandatory=False)
if self.env.DPKG_ARCHITECTURE:
deb_host_multiarch = self.cmd_and_log([self.env.DPKG_ARCHITECTURE[0], '-qDEB_HOST_MULTIARCH'])
BOOST_LIBS.insert(0, '/usr/lib/%s' % deb_host_multiarch.strip())
self.start_msg('Checking boost includes')
self.env['INCLUDES_%s' % var] = inc = self.boost_get_includes(**params)
versions = self.boost_get_version(inc)
self.env.BOOST_VERSION = versions[0]
self.env.BOOST_VERSION_NUMBER = int(versions[1])
self.end_msg("%d.%d.%d" % (int(versions[1]) / 100000,
int(versions[1]) / 100 % 1000,
int(versions[1]) % 100))
if Logs.verbose:
Logs.pprint('CYAN', ' path : %s' % self.env['INCLUDES_%s' % var])
self.start_msg('Checking boost includes')
self.env['INCLUDES_%s' % var] = inc = self.boost_get_includes(**params)
versions = self.boost_get_version(inc)
self.env.BOOST_VERSION = versions[0]
self.env.BOOST_VERSION_NUMBER = int(versions[1])
self.end_msg('%d.%d.%d' % (int(versions[1]) / 100000,
int(versions[1]) / 100 % 1000,
int(versions[1]) % 100))
if Logs.verbose:
Logs.pprint('CYAN', ' path : %s' % self.env['INCLUDES_%s' % var])
self.env.DONE_FIND_BOOST_COMMON = True
if not params['lib'] and not params['stlib']:
return
@@ -429,7 +437,7 @@ def check_boost(self, *k, **kw):
self.env['STLIBPATH_%s' % var] = [path]
self.env['LIB_%s' % var] = libs
self.env['STLIB_%s' % var] = stlibs
self.end_msg('ok')
self.end_msg(' '.join(libs + stlibs))
if Logs.verbose:
Logs.pprint('CYAN', ' path : %s' % path)
Logs.pprint('CYAN', ' shared libs : %s' % libs)
@@ -450,15 +458,18 @@ def check_boost(self, *k, **kw):
self.check_cxx(fragment=BOOST_ERROR_CODE, use=var, execute=False)
if has_lib('thread'):
self.check_cxx(fragment=BOOST_THREAD_CODE, use=var, execute=False)
if has_lib('log'):
if has_lib('log') or has_lib('log_setup'):
if not has_lib('thread'):
self.env['DEFINES_%s' % var] += ['BOOST_LOG_NO_THREADS']
if has_shlib('log'):
if has_shlib('log') or has_shlib('log_setup'):
self.env['DEFINES_%s' % var] += ['BOOST_LOG_DYN_LINK']
self.check_cxx(fragment=BOOST_LOG_CODE, use=var, execute=False)
if has_lib('log_setup'):
self.check_cxx(fragment=BOOST_LOG_SETUP_CODE, use=var, execute=False)
else:
self.check_cxx(fragment=BOOST_LOG_CODE, use=var, execute=False)
if params.get('linkage_autodetect', False):
self.start_msg("Attempting to detect boost linkage flags")
self.start_msg('Attempting to detect boost linkage flags')
toolset = self.boost_get_toolset(kw.get('toolset', ''))
if toolset in ('vc',):
# disable auto-linking feature, causing error LNK1181
@@ -480,10 +491,10 @@ def check_boost(self, *k, **kw):
# we attempt to play with some known-to-work CXXFLAGS combinations
for cxxflags in (['/MD', '/EHsc'], []):
self.env.stash()
self.env["CXXFLAGS_%s" % var] += cxxflags
self.env['CXXFLAGS_%s' % var] += cxxflags
try:
try_link()
self.end_msg("ok: winning cxxflags combination: %s" % (self.env["CXXFLAGS_%s" % var]))
self.end_msg('ok: winning cxxflags combination: %s' % (self.env['CXXFLAGS_%s' % var]))
exc = None
break
except Errors.ConfigurationError as e:
@@ -491,17 +502,17 @@ def check_boost(self, *k, **kw):
exc = e
if exc is not None:
self.end_msg("Could not auto-detect boost linking flags combination, you may report it to boost.py author", ex=exc)
self.end_msg('Could not auto-detect boost linking flags combination, you may report it to boost.py author', ex=exc)
self.fatal('The configuration failed')
else:
self.end_msg("Boost linkage flags auto-detection not implemented (needed ?) for this toolchain")
self.end_msg('Boost linkage flags auto-detection not implemented (needed ?) for this toolchain')
self.fatal('The configuration failed')
else:
self.start_msg('Checking for boost linkage')
try:
try_link()
except Errors.ConfigurationError as e:
self.end_msg("Could not link against boost libraries using supplied options")
self.end_msg('Could not link against boost libraries using supplied options', 'YELLOW')
self.fatal('The configuration failed')
self.end_msg('ok')
+104 -77
View File
@@ -1,10 +1,13 @@
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
import platform
from waflib import Configure, Logs, Utils
def options(opt):
opt.add_option('--debug', '--with-debug', action='store_true', default=False,
help='Compile in debugging mode with minimal optimizations (-O0 or -Og)')
help='Compile in debugging mode with minimal optimizations (-Og)')
def configure(conf):
conf.start_msg('Checking C++ compiler version')
@@ -15,17 +18,27 @@ def configure(conf):
errmsg = ''
warnmsg = ''
if cxx == 'gcc':
if ccver < (4, 8, 2):
if ccver < (7, 4, 0):
errmsg = ('The version of gcc you are using is too old.\n'
'The minimum supported gcc version is 4.8.2.')
'The minimum supported gcc version is 9.3.')
elif ccver < (9, 3, 0):
warnmsg = ('Using a version of gcc older than 9.3 is not '
'officially supported and may result in build failures.')
conf.flags = GccFlags()
elif cxx == 'clang':
if ccver < (3, 4, 0):
if Utils.unversioned_sys_platform() == 'darwin':
if ccver < (10, 0, 0):
errmsg = ('The version of Xcode you are using is too old.\n'
'The minimum supported Xcode version is 12.4.')
elif ccver < (12, 0, 0):
warnmsg = ('Using a version of Xcode older than 12.4 is not '
'officially supported and may result in build failures.')
elif ccver < (7, 0, 0):
errmsg = ('The version of clang you are using is too old.\n'
'The minimum supported clang version is 3.4.0.')
'The minimum supported clang version is 7.0.')
conf.flags = ClangFlags()
else:
warnmsg = 'Note: %s compiler is unsupported' % cxx
warnmsg = f'{cxx} compiler is unsupported'
conf.flags = CompilerFlags()
if errmsg:
@@ -33,18 +46,19 @@ def configure(conf):
conf.fatal(errmsg)
elif warnmsg:
conf.end_msg(ccverstr, color='YELLOW')
Logs.warn(warnmsg)
Logs.warn('WARNING: ' + warnmsg)
else:
conf.end_msg(ccverstr)
conf.areCustomCxxflagsPresent = (len(conf.env.CXXFLAGS) > 0)
conf.areCustomCxxflagsPresent = len(conf.env.CXXFLAGS) > 0
# General flags are always applied (e.g., selecting C++11 mode)
# General flags are always applied (e.g., selecting C++ language standard)
generalFlags = conf.flags.getGeneralFlags(conf)
conf.add_supported_cxxflags(generalFlags['CXXFLAGS'])
conf.add_supported_linkflags(generalFlags['LINKFLAGS'])
conf.env.DEFINES += generalFlags['DEFINES']
@Configure.conf
def check_compiler_flags(conf):
# Debug or optimized CXXFLAGS and LINKFLAGS are applied only if the
@@ -67,10 +81,11 @@ def check_compiler_flags(conf):
conf.env.DEFINES += extraFlags['DEFINES']
@Configure.conf
def add_supported_cxxflags(self, cxxflags):
"""
Check which cxxflags are supported by compiler and add them to env.CXXFLAGS variable
Check which cxxflags are supported by the active compiler and add them to env.CXXFLAGS variable.
"""
if len(cxxflags) == 0:
return
@@ -86,10 +101,11 @@ def add_supported_cxxflags(self, cxxflags):
self.end_msg(' '.join(supportedFlags))
self.env.prepend_value('CXXFLAGS', supportedFlags)
@Configure.conf
def add_supported_linkflags(self, linkflags):
"""
Check which linkflags are supported by compiler and add them to env.LINKFLAGS variable
Check which linkflags are supported by the active compiler and add them to env.LINKFLAGS variable.
"""
if len(linkflags) == 0:
return
@@ -106,13 +122,17 @@ def add_supported_linkflags(self, linkflags):
self.env.prepend_value('LINKFLAGS', supportedFlags)
class CompilerFlags(object):
class CompilerFlags:
def getCompilerVersion(self, conf):
return tuple(int(i) for i in conf.env.CC_VERSION)
def getGeneralFlags(self, conf):
"""Get dict of CXXFLAGS, LINKFLAGS, and DEFINES that are always needed"""
return {'CXXFLAGS': [], 'LINKFLAGS': [], 'DEFINES': []}
return {
'CXXFLAGS': [],
'LINKFLAGS': [],
'DEFINES': ['BOOST_ASIO_NO_DEPRECATED', 'BOOST_FILESYSTEM_NO_DEPRECATED'],
}
def getDebugFlags(self, conf):
"""Get dict of CXXFLAGS, LINKFLAGS, and DEFINES that are needed only in debug mode"""
@@ -122,93 +142,100 @@ class CompilerFlags(object):
"""Get dict of CXXFLAGS, LINKFLAGS, and DEFINES that are needed only in optimized mode"""
return {'CXXFLAGS': [], 'LINKFLAGS': [], 'DEFINES': ['NDEBUG']}
class GccBasicFlags(CompilerFlags):
class GccClangCommonFlags(CompilerFlags):
"""
This class defines basic flags that work for both gcc and clang compilers
This class defines common flags that work for both gcc and clang compilers.
"""
def getGeneralFlags(self, conf):
flags = super(GccBasicFlags, self).getGeneralFlags(conf)
flags['CXXFLAGS'] += ['-std=c++11']
flags = super().getGeneralFlags(conf)
flags['CXXFLAGS'] += ['-std=c++17']
if Utils.unversioned_sys_platform() != 'darwin':
flags['LINKFLAGS'] += ['-fuse-ld=lld']
return flags
__cxxFlags = [
'-fdiagnostics-color',
'-Wall',
'-Wextra',
'-Wpedantic',
'-Wenum-conversion',
'-Wextra-semi',
'-Wnon-virtual-dtor',
'-Wno-unused-parameter',
]
__linkFlags = ['-Wl,-O1']
def getDebugFlags(self, conf):
flags = super(GccBasicFlags, self).getDebugFlags(conf)
flags['CXXFLAGS'] += ['-O0',
'-Og', # gcc >= 4.8, clang >= 4.0
'-g3',
'-pedantic',
'-Wall',
'-Wextra',
'-Werror',
'-Wnon-virtual-dtor',
'-Wno-error=deprecated-declarations', # Bug #3795
'-Wno-error=maybe-uninitialized', # Bug #1615
'-Wno-unused-parameter',
]
flags['LINKFLAGS'] += ['-fuse-ld=gold', '-Wl,-O1']
flags = super().getDebugFlags(conf)
flags['CXXFLAGS'] += ['-Og', '-g'] + self.__cxxFlags + [
'-Werror',
'-Wno-error=deprecated-declarations', # Bug #3795
'-Wno-error=maybe-uninitialized', # Bug #1615
]
flags['LINKFLAGS'] += self.__linkFlags
return flags
def getOptimizedFlags(self, conf):
flags = super(GccBasicFlags, self).getOptimizedFlags(conf)
flags['CXXFLAGS'] += ['-O2',
'-g',
'-pedantic',
'-Wall',
'-Wextra',
'-Wnon-virtual-dtor',
'-Wno-unused-parameter',
]
flags['LINKFLAGS'] += ['-fuse-ld=gold', '-Wl,-O1']
flags = super().getOptimizedFlags(conf)
flags['CXXFLAGS'] += ['-O2', '-g1'] + self.__cxxFlags
flags['LINKFLAGS'] += self.__linkFlags
return flags
class GccFlags(GccBasicFlags):
class GccFlags(GccClangCommonFlags):
__cxxFlags = [
'-Wcatch-value=2',
'-Wcomma-subscript', # enabled by default in C++20
'-Wduplicated-branches',
'-Wduplicated-cond',
'-Wlogical-op',
'-Wredundant-tags',
'-Wvolatile', # enabled by default in C++20
]
def getDebugFlags(self, conf):
flags = super(GccFlags, self).getDebugFlags(conf)
if self.getCompilerVersion(conf) < (5, 1, 0):
flags['CXXFLAGS'] += ['-Wno-missing-field-initializers']
flags['CXXFLAGS'] += ['-fdiagnostics-color'] # gcc >= 4.9
flags = super().getDebugFlags(conf)
flags['CXXFLAGS'] += self.__cxxFlags
if platform.machine() == 'armv7l':
flags['CXXFLAGS'] += ['-Wno-psabi'] # Bug #5106
return flags
def getOptimizedFlags(self, conf):
flags = super(GccFlags, self).getOptimizedFlags(conf)
if self.getCompilerVersion(conf) < (5, 1, 0):
flags['CXXFLAGS'] += ['-Wno-missing-field-initializers']
flags['CXXFLAGS'] += ['-fdiagnostics-color'] # gcc >= 4.9
flags = super().getOptimizedFlags(conf)
flags['CXXFLAGS'] += self.__cxxFlags
if platform.machine() == 'armv7l':
flags['CXXFLAGS'] += ['-Wno-psabi'] # Bug #5106
return flags
class ClangFlags(GccBasicFlags):
class ClangFlags(GccClangCommonFlags):
def getGeneralFlags(self, conf):
flags = super(ClangFlags, self).getGeneralFlags(conf)
if Utils.unversioned_sys_platform() == 'darwin' and self.getCompilerVersion(conf) >= (9, 0, 0):
flags = super().getGeneralFlags(conf)
if Utils.unversioned_sys_platform() == 'darwin':
# Bug #4296
flags['CXXFLAGS'] += [['-isystem', '/usr/local/include'], # for Homebrew
['-isystem', '/opt/local/include']] # for MacPorts
brewdir = '/opt/homebrew' if platform.machine() == 'arm64' else '/usr/local'
flags['CXXFLAGS'] += [
['-isystem', f'{brewdir}/include'], # for Homebrew
['-isystem', '/opt/local/include'], # for MacPorts
]
elif Utils.unversioned_sys_platform() == 'freebsd':
# Bug #4790
flags['CXXFLAGS'] += [['-isystem', '/usr/local/include']]
return flags
__cxxFlags = [
'-Wundefined-func-template',
'-Wno-unused-local-typedef', # Bugs #2657 and #3209
]
def getDebugFlags(self, conf):
flags = super(ClangFlags, self).getDebugFlags(conf)
flags['CXXFLAGS'] += ['-fcolor-diagnostics',
'-Wextra-semi',
'-Wundefined-func-template',
'-Wno-error=deprecated-register',
'-Wno-error=infinite-recursion', # Bug #3358
'-Wno-error=keyword-macro', # Bug #3235
'-Wno-error=unneeded-internal-declaration', # Bug #1588
'-Wno-unused-local-typedef', # Bugs #2657 and #3209
]
version = self.getCompilerVersion(conf)
if version < (3, 9, 0) or (Utils.unversioned_sys_platform() == 'darwin' and version < (8, 1, 0)):
flags['CXXFLAGS'] += ['-Wno-unknown-pragmas']
flags = super().getDebugFlags(conf)
flags['CXXFLAGS'] += self.__cxxFlags
return flags
def getOptimizedFlags(self, conf):
flags = super(ClangFlags, self).getOptimizedFlags(conf)
flags['CXXFLAGS'] += ['-fcolor-diagnostics',
'-Wextra-semi',
'-Wundefined-func-template',
'-Wno-unused-local-typedef', # Bugs #2657 and #3209
]
version = self.getCompilerVersion(conf)
if version < (3, 9, 0) or (Utils.unversioned_sys_platform() == 'darwin' and version < (8, 1, 0)):
flags['CXXFLAGS'] += ['-Wno-unknown-pragmas']
flags = super().getOptimizedFlags(conf)
flags['CXXFLAGS'] += self.__cxxFlags
return flags
+8 -8
View File
@@ -44,28 +44,28 @@ def apply_sphinx(self):
task.inputs.append(conf)
confdir = conf.parent.abspath()
buildername = getattr(self, "builder", "html")
srcdir = getattr(self, "srcdir", confdir)
outdir = self.path.find_or_declare(getattr(self, "outdir", buildername)).get_bld()
doctreedir = getattr(self, "doctreedir", os.path.join(outdir.abspath(), ".doctrees"))
buildername = getattr(self, 'builder', 'html')
srcdir = getattr(self, 'srcdir', confdir)
outdir = self.path.find_or_declare(getattr(self, 'outdir', buildername)).get_bld()
doctreedir = getattr(self, 'doctreedir', os.path.join(outdir.abspath(), '.doctrees'))
task.env['BUILDERNAME'] = buildername
task.env['SRCDIR'] = srcdir
task.env['DOCTREEDIR'] = doctreedir
task.env['OUTDIR'] = outdir.abspath()
task.env['VERSION'] = "version=%s" % self.VERSION
task.env['RELEASE'] = "release=%s" % self.VERSION
task.env['VERSION'] = 'version=%s' % self.version
task.env['RELEASE'] = 'release=%s' % getattr(self, 'release', self.version)
import imp
confData = imp.load_source('sphinx_conf', conf.abspath())
if buildername == "man":
if buildername == 'man':
for i in confData.man_pages:
target = outdir.find_or_declare('%s.%d' % (i[1], i[4]))
task.outputs.append(target)
if self.install_path:
self.bld.install_files("%s/man%d/" % (self.install_path, i[4]), target)
self.bld.install_files('%s/man%d/' % (self.install_path, i[4]), target)
else:
task.outputs.append(outdir)
+16 -7
View File
@@ -1,8 +1,17 @@
ChronoSync authors
==================
# ChronoSync Authors
- Zhenkai Zhu <http://irl.cs.ucla.edu/~zhenkai/>
- Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
- Chaoyi Bian <bcy@pku.edu.cn>
- Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/web/index.html>
- Sonu Mishra <https://www.linkedin.com/in/mishrasonu>
The following lists maintainers, primary developers, and all much-appreciated contributors to ChronoSync in alphabetical order.
The specific contributions of individual authors can be obtained from the git history of the [official ChronoSync repository](https://github.com/named-data/ChronoSync).
If you would like to become a contributor to the official repository, please follow the recommendations in <https://github.com/named-data/.github/blob/main/CONTRIBUTING.md>.
* ***(Maintainer)*** Alexander Afanasyev <https://users.cs.fiu.edu/~afanasyev>
* Chaoyi Bian <https://github.com/bcy>
* Qiuhan Ding <https://irl.cs.ucla.edu/~qiuhanding>
* Ashlesh Gawande <https://www.linkedin.com/in/agawande>
* Nick Gordon <https://github.com/gorgonical>
* Sonu Mishra <https://sites.google.com/site/sonukrmishra93>
* Eric Newberry <https://ericnewberry.com>
* Davide Pesavento <https://github.com/Pesa>
* Junxiao Shi <https://cs.arizona.edu/~shijunxiao>
* Yingdi Yu <https://irl.cs.ucla.edu/~yingdi>
* ***(Former Maintainer)*** Zhenkai Zhu <https://irl.cs.ucla.edu/~zhenkai>
+354 -356
View File
File diff suppressed because it is too large Load Diff
+1 -2
View File
@@ -3,8 +3,7 @@ libdir=@LIBDIR@
includedir=@INCLUDEDIR@
Name: ChronoSync
Description: ChronoSync library
Description: NDN ChronoSync library
Version: @VERSION@
Libs: -L${libdir} -lChronoSync
Cflags: -I${includedir}
+31 -28
View File
@@ -1,10 +1,11 @@
ChronoSync: synchronization library for distributed realtime applications for NDN
=================================================================================
# ChronoSync: synchronization library for distributed realtime applications for NDN
[![Build Status](https://travis-ci.org/named-data/ChronoSync.svg?branch=master)](https://travis-ci.org/named-data/ChronoSync)
[![CI](https://github.com/named-data/ChronoSync/actions/workflows/ci.yml/badge.svg)](https://github.com/named-data/ChronoSync/actions/workflows/ci.yml)
[![Docs](https://github.com/named-data/ChronoSync/actions/workflows/docs.yml/badge.svg)](https://github.com/named-data/ChronoSync/actions/workflows/docs.yml)
![Language](https://img.shields.io/badge/C%2B%2B-17-blue)
![Latest version](https://img.shields.io/github/v/tag/named-data/ChronoSync?label=Latest%20version)
If you are new to the NDN community of software generally, read the
[Contributor's Guide](https://github.com/named-data/NFD/blob/master/CONTRIBUTING.md).
> DEPRECATION NOTICE: ChronoSync's design is outdated. We recommend using more recent sync protocols, such as [PSync](https://github.com/named-data/PSync) or [StateVectorSync](https://named-data.github.io/StateVectorSync/).
In supporting many distributed applications, such as group text messaging, file sharing,
and joint editing, a basic requirement is the efficient and robust synchronization of
@@ -19,39 +20,41 @@ be inferred from the digests and disseminated efficiently to all parties. With
complete and up-to-date knowledge of the dataset changes, applications can decide whether
or when to fetch which pieces of the data.
ChronoSync uses [ndn-cxx](https://github.com/named-data/ndn-cxx) library as NDN development
library.
ChronoSync uses the [ndn-cxx](https://github.com/named-data/ndn-cxx) library.
ChronoSync is an open source project licensed under GPL 3.0 (see `COPYING.md` for more
detail). We highly welcome all contributions to the ChronoSync code base, provided that
they can licensed under GPL 3.0+ or other compatible license.
Feedback
--------
Please submit any bugs or issues to the **ChronoSync** issue tracker:
* https://redmine.named-data.net/projects/chronosync
Installation instructions
-------------------------
## Installation
### Prerequisites
Required:
* [ndn-cxx and its dependencies](https://named-data.net/doc/ndn-cxx/)
* [ndn-cxx and its dependencies](https://docs.named-data.net/ndn-cxx/current/INSTALL.html)
### Build
To build ChronoSync from the source:
To build ChronoSync from source:
./waf configure
./waf
sudo ./waf install
To build on memory constrained platform, please use `./waf -j1` instead of `./waf`. The
command will disable parallel compilation.
To build on memory constrained systems, please use `./waf -j1` instead of `./waf`. This
will disable parallel compilation.
If configured with tests: `./waf configure --with-tests`), the above commands will also
generate unit tests in `./build/unit-tests`
If configured with tests (`./waf configure --with-tests`), the above commands will also
build a suite of unit tests that can be run with `./build/unit-tests`.
## Reporting bugs
Please submit any bug reports or feature requests to the
[ChronoSync issue tracker](https://redmine.named-data.net/projects/chronosync/issues).
## Contributing
Contributions to ChronoSync are greatly appreciated and can be made through our
[Gerrit code review site](https://gerrit.named-data.net/).
If you are new to the NDN software community, please read our [Contributor's Guide](
https://github.com/named-data/.github/blob/main/CONTRIBUTING.md) to get started.
## License
ChronoSync is free software distributed under the GNU General Public License version 3.
See [`COPYING.md`](COPYING.md) for details.
+65 -15
View File
@@ -1,32 +1,82 @@
Release Notes
=============
# Release Notes
## Version 0.5.5
- The minimum build requirements have been increased as follows:
- Either GCC >= 7.4.0 or Clang >= 6.0 is required on Linux
- On macOS, Xcode 11.3 or later is recommended; older versions may still work but are
not officially supported
- Boost >= 1.65.1 and ndn-cxx >= 0.8.1 are required on all platforms
- Sphinx 4.0 or later is required to build the documentation
- Switch to C++17
- Fix compilation against the latest version of ndn-cxx
- Stop using the `gold` linker on Linux; prefer instead linking with `lld` if installed
- Upgrade `waf` to version 2.0.24
## Version 0.5.4
- The build requirements have been increased to require Clang >= 4.0, Xcode >= 9.0,
and Python >= 3.6. Meanwhile, it is *recommended* to use GCC >= 7.4.0 and
Boost >= 1.65.1. This effectively drops official support for Ubuntu 16.04 when
using distribution-provided packages; ChronoSync may still work on this platform,
but we provide no official support for it.
- Exceptions are now thrown using `NDN_THROW` instead of `BOOST_THROW_EXCEPTION`
- The private header files `config.hpp`, `common.hpp`, `bzip2-helper.hpp`,
`mi-tag.hpp`, and `tlv.hpp` have been moved to a `detail` subdirectory
- Fix compilation against the latest version of ndn-cxx
- Fix incompatibility with the C++20 `<version>` header
- Upgrade `waf` to version 2.0.21
## Version 0.5.3
- Schedule sync Interest when receiving a NACK with reason `NoRoute` (Issue #5012)
- Use properly seeded pseudorandom number generator from ndn-cxx
- Fix compilation against the latest version of ndn-cxx
- Upgrade `waf` to version 2.0.14 and other build system improvements
## Version 0.5.2
- The build requirements have been upgraded to gcc >= 5.3 or clang >= 3.6.
This effectively drops support for all versions of Ubuntu older
than 16.04 that use distribution-provided compilers and packages.
- Transition to v0.3 packet format (Issues #4691 and #4684)
## Version 0.5.1
- Fix forceful shutdown of `Face` when destructing `Logic` instance
(Issue #4525)
- Fix forceful shutdown of `Face` when destructing `Logic` instance (Issue #4525)
- Fix compilation against the latest version of ndn-cxx library
- Fix compilation against the latest version of ndn-cxx
- Upgrade `waf` to the latest version and other improvements
- Upgrade `waf` to version 2.0.6 and other build system improvements
## Version 0.5.0
- **Breaking change** Use bzip2 compression of sync Data payload (Issue #4140)
- *Breaking change:* Use bzip2 compression of sync Data payload (Issue #4140)
- Disallow Interest loopback on sync prefix (Issue #3979)
- Avoid ABI differences between debug/optimized modes (Issue #4496)
- Extend Socket and Logic API:
- Extend `Socket` and `Logic` API:
- Allow customization of sync interest lifetime (Issue #4490)
- Limit the size of created sync Data and enable ability to
customize the maximum packet size through environment variable
(Issue #4140)
- Allow override of the session number
- Allow customization of sync Interest lifetime (Issue #4490)
- Limit the size of created sync Data and enable ability to customize
the maximum packet size through environment variable (Issue #4140)
- Allow override of the session number
- Disable use of Exclude filter (preparation for Exclude deprecation
in NDN and implementation was only partially correct)
+52 -230
View File
@@ -1,258 +1,80 @@
# -*- coding: utf-8 -*-
# Configuration file for the Sphinx documentation builder.
#
# NFD - Named Data Networking Forwarding Daemon documentation build configuration file, created by
# sphinx-quickstart on Sun Apr 6 19:58:22 2014.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
# For the full list of built-in configuration values, see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
import importlib.util
import sys
import os
import re
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))
# -- Project information -----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
# -- General configuration ------------------------------------------------
project = 'ChronoSync: A Synchronization Protocol for NDN'
copyright = 'Copyright © 2012-2023 Regents of the University of California.'
author = 'Named Data Networking Project'
# If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0'
# The short X.Y version.
#version = ''
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.todo',
]
def addExtensionIfExists(extension):
try:
__import__(extension)
extensions.append(extension)
except ImportError:
sys.stderr.write("Extension '%s' in not available. "
"Some documentation may not build correctly.\n" % extension)
sys.stderr.write("To install, use \n"
" sudo pip install %s\n" % extension.replace('.', '-'))
if sys.version_info[0] >= 3:
addExtensionIfExists('sphinxcontrib.doxylink')
# sphinxcontrib.googleanalytics is currently not working with the latest version of sphinx
# if os.getenv('GOOGLE_ANALYTICS', None):
# addExtensionIfExists('sphinxcontrib.googleanalytics')
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'ChronoSync: A Synchronization Protocol in NDN'
copyright = u'2017, Named Data Networking Project'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None
# The full version, including alpha/beta/rc tags.
#release = ''
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = []
# The reST default role (used for this markup: `text`) to use for all
# documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# If true, keep warnings as "system message" paragraphs in the built documents.
#keep_warnings = False
today_fmt = '%Y-%m-%d'
# -- Options for HTML output ----------------------------------------------
# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
needs_sphinx = '4.0'
extensions = [
'sphinx.ext.extlinks',
'sphinx.ext.todo',
]
def addExtensionIfExists(extension: str):
try:
if importlib.util.find_spec(extension) is None:
raise ModuleNotFoundError(extension)
except (ImportError, ValueError):
sys.stderr.write(f'WARNING: Extension {extension!r} not found. '
'Some documentation may not build correctly.\n')
else:
extensions.append(extension)
addExtensionIfExists('sphinxcontrib.doxylink')
templates_path = ['_templates']
exclude_patterns = ['Thumbs.db', '.DS_Store', 'RELEASE_NOTES.rst']
# -- Options for HTML output -------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
# html_theme = 'default'
html_theme = 'named_data_theme'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
html_theme_path = ['./']
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
html_theme_path = ['.']
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
# html_static_path = ['_static']
html_static_path = ['_static']
# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
# directly to the root of the documentation.
#html_extra_path = []
html_copy_source = False
html_show_sourcelink = False
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_domain_indices = True
# If false, no index is generated.
#html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
html_file_suffix = ".html"
# Output file base name for HTML help builder.
htmlhelp_basename = 'ChronoSync-docs'
# Disable syntax highlighting of code blocks by default.
highlight_language = 'none'
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#'preamble': '',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
('index', 'ChronoSync-docs.tex', u'A Synchronization Protocol in NDN',
u'Named Data Networking Project', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# If true, show page references after internal links.
#latex_show_pagerefs = False
# If true, show URL addresses after external links.
#latex_show_urls = False
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_domain_indices = True
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
]
# If true, show URL addresses after external links.
man_show_urls = True
# ---- Custom options --------
# -- Misc options ------------------------------------------------------------
doxylink = {
'ChronoSync' : ('ChronoSync.tag', 'doxygen/'),
'ChronoSync': ('ChronoSync.tag', 'doxygen/'),
}
if os.getenv('GOOGLE_ANALYTICS', None):
googleanalytics_id = os.environ['GOOGLE_ANALYTICS']
googleanalytics_enabled = True
exclude_patterns = ['RELEASE_NOTES.rst']
extlinks = {
'issue': ('https://redmine.named-data.net/issues/%s', 'issue #%s'),
}
+16 -65
View File
@@ -68,7 +68,7 @@ OUTPUT_DIRECTORY = docs/doxygen
# performance problems for the file system.
# The default value is: NO.
CREATE_SUBDIRS = YES
CREATE_SUBDIRS = NO
# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
# characters to appear in the names of generated files. If set to NO, non-ASCII
@@ -140,7 +140,7 @@ INLINE_INHERITED_MEMB = YES
# shortest path that makes the file name unique will be used
# The default value is: YES.
FULL_PATH_NAMES = NO
FULL_PATH_NAMES = YES
# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
# Stripping is only done if one of the specified strings matches the left-hand
@@ -161,7 +161,7 @@ STRIP_FROM_PATH =
# specify the list of include paths that are normally passed to the compiler
# using the -I flag.
STRIP_FROM_INC_PATH =
STRIP_FROM_INC_PATH = ..
# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
# less readable) file names. This can be useful is your file systems doesn't
@@ -230,12 +230,6 @@ TAB_SIZE = 4
ALIASES =
# This tag can be used to specify a number of word-keyword mappings (TCL only).
# A mapping has the form "name=value". For example adding "class=itcl::class"
# will allow you to use the command class in the itcl::class meaning.
TCL_SUBST =
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
# only. Doxygen will then generate output that is more tailored for C. For
# instance, some of the names that are used will be different. The list of all
@@ -443,7 +437,7 @@ EXTRACT_PACKAGE = NO
# included in the documentation.
# The default value is: NO.
EXTRACT_STATIC = YES
EXTRACT_STATIC = NO
# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
# locally in source files will be included in the documentation. If set to NO,
@@ -451,7 +445,7 @@ EXTRACT_STATIC = YES
# for Java sources.
# The default value is: YES.
EXTRACT_LOCAL_CLASSES = YES
EXTRACT_LOCAL_CLASSES = NO
# This flag is only useful for Objective-C code. If set to YES, local methods,
# which are defined in the implementation section but not in the interface are
@@ -1047,13 +1041,6 @@ VERBATIM_HEADERS = YES
ALPHABETICAL_INDEX = YES
# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
# which the alphabetical index list will be split.
# Minimum value: 1, maximum value: 20, default value: 5.
# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
COLS_IN_ALPHA_INDEX = 5
# In case all classes in a project start with a common prefix, all classes will
# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
# can be used to specify a prefix (or a list of prefixes) that should be ignored
@@ -1191,7 +1178,7 @@ HTML_COLORSTYLE_GAMMA = 91
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_TIMESTAMP = YES
HTML_TIMESTAMP = NO
# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
# documentation will contain sections that can be hidden and shown after the
@@ -1752,16 +1739,6 @@ LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
# code with syntax highlighting in the LaTeX output.
#
# Note that which sources are shown also depends on other settings such as
# SOURCE_BROWSER.
# The default value is: NO.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_SOURCE_CODE = NO
# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
# bibliography, e.g. plainnat, or ieeetr. See
# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
@@ -1834,16 +1811,6 @@ RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
# with syntax highlighting in the RTF output.
#
# Note that which sources are shown also depends on other settings such as
# SOURCE_BROWSER.
# The default value is: NO.
# This tag requires that the tag GENERATE_RTF is set to YES.
RTF_SOURCE_CODE = NO
#---------------------------------------------------------------------------
# Configuration options related to the man page output
#---------------------------------------------------------------------------
@@ -1933,15 +1900,6 @@ GENERATE_DOCBOOK = NO
DOCBOOK_OUTPUT = docbook
# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
# program listings (including syntax highlighting and cross-referencing
# information) to the DOCBOOK output. Note that enabling this will significantly
# increase the size of the DOCBOOK output.
# The default value is: NO.
# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
DOCBOOK_PROGRAMLISTING = NO
#---------------------------------------------------------------------------
# Configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
@@ -2050,8 +2008,16 @@ INCLUDE_FILE_PATTERNS =
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
PREDEFINED = DOXYGEN \
NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(x)= \
NDN_LOG_INIT(x)= \
NDN_LOG_MEMBER_DECL()= \
NDN_LOG_MEMBER_DECL_SPECIALIZED(x)= \
NDN_LOG_MEMBER_INIT(x,y)= \
NDN_LOG_MEMBER_INIT_SPECIALIZED(x,y)= \
CHRONOSYNC_PUBLIC_WITH_TESTS_ELSE_PROTECTED=protected \
CHRONOSYNC_PUBLIC_WITH_TESTS_ELSE_PRIVATE=private \
NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(x)=
CHRONOSYNC_PROTECTED_WITH_TESTS_ELSE_PRIVATE=private \
CHRONOSYNC_VIRTUAL_WITH_TESTS=
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
# tag can be used to specify a list of macro names that should be expanded. The
@@ -2118,12 +2084,6 @@ EXTERNAL_GROUPS = YES
EXTERNAL_PAGES = YES
# The PERL_PATH should be the absolute path and name of the perl script
# interpreter (i.e. the result of 'which perl').
# The default file (with absolute path) is: /usr/bin/perl.
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
@@ -2137,15 +2097,6 @@ PERL_PATH = /usr/bin/perl
CLASS_DIAGRAMS = YES
# You can define message sequence charts within doxygen comments using the \msc
# command. Doxygen will then run the mscgen tool (see:
# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
# documentation. The MSCGEN_PATH tag allows you to specify the directory where
# the mscgen tool resides. If left empty the tool is assumed to be found in the
# default search path.
MSCGEN_PATH =
# You can include diagrams made with dia in doxygen documentation. Doxygen will
# then run dia to produce the diagram and insert it in the documentation. The
# DIA_PATH tag allows you to specify the directory where the dia binary resides.
@@ -2166,7 +2117,7 @@ HIDE_UNDOC_RELATIONS = YES
# set to NO
# The default value is: YES.
HAVE_DOT = YES
HAVE_DOT = @HAVE_DOT@
# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
# to run in parallel. When set to 0 doxygen will base this on the number of
+9 -8
View File
@@ -1,26 +1,27 @@
ChronoSync - A synchronization Protocol in NDN
ChronoSync: A Synchronization Protocol for NDN
==============================================
.. toctree::
:hidden:
:maxdepth: 3
DesignDoc
design
* :doc:`DesignDoc`
Documentation
-------------
**Additional documentation**
* `API documentation (doxygen) <doxygen/annotated.html>`_
* :doc:`design`
* `API documentation (doxygen) <doxygen/annotated.html>`__
Downloading
-----------
* `Source code GitHub git repository <https://github.com/named-data/ChronoSync>`_.
* `Source code git repository <https://github.com/named-data/ChronoSync>`__
License
-------
ChronoSync 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.
version 3 of the License, or (at your option) any later version. See `COPYING.md
<https://github.com/named-data/ChronoSync/blob/master/COPYING.md>`__ for details.
+2 -3
View File
@@ -12,7 +12,7 @@
<div class="row">
<div class="three columns">
<div id="logo">
<a href="http://named-data.net" title="A Future Internet Architecture"><img src="http://named-data.net/wp-content/uploads/cropped-20130722_Logo2.png" alt="" /></a>
<a href="https://named-data.net" title="A Future Internet Architecture"><img src="https://named-data.net/wp-content/uploads/cropped-20130722_Logo2.png" alt="" /></a>
</div><!--logo end-->
</div>
@@ -41,7 +41,6 @@
<h3>{{ _('Developer documentation') }}</h3>
<ul>
<li class="toctree-l1"><a class="reference internal" href="doxygen/annotated.html">API documentation (doxygen)</a></li>
<li class="toctree-l1"><a class="reference internal" href="code-style.html">ndn-cxx Code Style and Coding Guidelines</a></li>
</ul>
{%- endblock %}
@@ -75,7 +74,7 @@
<div class="row">
<div class="twelve columns">
<div id="copyright">This research is partially supported by NSF (Award <a href="http://www.nsf.gov/awardsearch/showAward?AWD_ID=1040868" target="_blank>">CNS-1040868</a>)<br/><br/><a rel="license" href="http://creativecommons.org/licenses/by/3.0/deed.en_US" target="_blank">Creative Commons Attribution 3.0 Unported License</a> except where noted.</div>
<div id="copyright">This research is partially supported by NSF (Award <a href="https://www.nsf.gov/awardsearch/showAward?AWD_ID=1040868" target="_blank>">CNS-1040868</a>)<br/><br/><a rel="license" href="https://creativecommons.org/licenses/by/3.0/deed.en_US" target="_blank">Creative Commons Attribution 3.0 Unported License</a> except where noted.</div>
</div>
</div>
+1 -1
View File
@@ -26,7 +26,7 @@ $mathjax
<div class="row">
<div class="three columns">
<div id="logo">
<a href="http://named-data.net" title="A Future Internet Architecture"><img src="http://named-data.net/wp-content/uploads/cropped-20130722_Logo2.png" alt="" /></a>
<a href="https://named-data.net" title="A Future Internet Architecture"><img src="https://named-data.net/wp-content/uploads/cropped-20130722_Logo2.png" alt="" /></a>
</div><!--logo end-->
</div>
@@ -1,6 +1,6 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012-2018 University of California, Los Angeles
* Copyright (c) 2012-2022 University of California, Los Angeles
*
* This file is part of ChronoSync, synchronization library for distributed realtime
* applications for NDN.
@@ -19,15 +19,15 @@
#include "bzip2-helper.hpp"
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/detail/iostream.hpp>
#include <boost/iostreams/filter/bzip2.hpp>
#include <boost/iostreams/copy.hpp>
#include <boost/iostreams/device/array.hpp>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filter/bzip2.hpp>
#include <boost/iostreams/stream.hpp>
#include <ndn-cxx/encoding/buffer-stream.hpp>
namespace chronosync {
namespace bzip2 {
namespace chronosync::bzip2 {
namespace bio = boost::iostreams;
@@ -38,7 +38,7 @@ compress(const char* buffer, size_t bufferSize)
bio::filtering_stream<bio::output> out;
out.push(bio::bzip2_compressor());
out.push(os);
bio::stream<bio::array_source> in(reinterpret_cast<const char*>(buffer), bufferSize);
bio::stream<bio::array_source> in(buffer, bufferSize);
bio::copy(in, out);
return os.buf();
}
@@ -50,10 +50,9 @@ decompress(const char* buffer, size_t bufferSize)
bio::filtering_stream<bio::output> out;
out.push(bio::bzip2_decompressor());
out.push(os);
bio::stream<bio::array_source> in(reinterpret_cast<const char*>(buffer), bufferSize);
bio::stream<bio::array_source> in(buffer, bufferSize);
bio::copy(in, out);
return os.buf();
}
} // namespace bzip2
} // namespace chronosync
} // namespace chronosync::bzip2
@@ -1,6 +1,6 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012-2018 University of California, Los Angeles
* Copyright (c) 2012-2022 University of California, Los Angeles
*
* This file is part of ChronoSync, synchronization library for distributed realtime
* applications for NDN.
@@ -17,13 +17,12 @@
* ChronoSync, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CHRONOSYNC_BZIP2_HELPER_HPP
#define CHRONOSYNC_BZIP2_HELPER_HPP
#ifndef CHRONOSYNC_DETAIL_BZIP2_HELPER_HPP
#define CHRONOSYNC_DETAIL_BZIP2_HELPER_HPP
#include <ndn-cxx/encoding/buffer.hpp>
namespace chronosync {
namespace bzip2 {
namespace chronosync::bzip2 {
/**
* @brief Compress @p buffer of size @p bufferSize with bzip2
@@ -37,7 +36,6 @@ compress(const char* buffer, size_t bufferSize);
std::shared_ptr<ndn::Buffer>
decompress(const char* buffer, size_t bufferSize);
} // namespace bzip2
} // namespace chronosync
} // namespace chronosync::bzip2
#endif // CHRONOSYNC_BZIP2_HELPER_HPP
#endif // CHRONOSYNC_DETAIL_BZIP2_HELPER_HPP
+15 -36
View File
@@ -1,6 +1,6 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012-2018 University of California, Los Angeles
* Copyright (c) 2012-2022 University of California, Los Angeles
*
* This file is part of ChronoSync, synchronization library for distributed realtime
* applications for NDN.
@@ -20,12 +20,12 @@
* @author Yingdi Yu <yingdi@cs.ucla.edu>
*/
#ifndef CHRONOSYNC_COMMON_HPP
#define CHRONOSYNC_COMMON_HPP
#ifndef CHRONOSYNC_DETAIL_COMMON_HPP
#define CHRONOSYNC_DETAIL_COMMON_HPP
#include "config.hpp"
#ifdef CHRONOSYNC_HAVE_TESTS
#ifdef CHRONOSYNC_WITH_TESTS
#define CHRONOSYNC_VIRTUAL_WITH_TESTS virtual
#define CHRONOSYNC_PUBLIC_WITH_TESTS_ELSE_PROTECTED public
#define CHRONOSYNC_PUBLIC_WITH_TESTS_ELSE_PRIVATE public
@@ -38,70 +38,49 @@
#endif
#include <cstddef>
#include <list>
#include <queue>
#include <functional>
#include <memory>
#include <set>
#include <vector>
#include <tuple>
#include <ndn-cxx/data.hpp>
#include <ndn-cxx/face.hpp>
#include <ndn-cxx/interest.hpp>
#include <ndn-cxx/security/key-chain.hpp>
#include <ndn-cxx/security/signing-helpers.hpp>
#include <ndn-cxx/security/v2/validator.hpp>
#include <ndn-cxx/security/validator.hpp>
#include <ndn-cxx/security/validator-config.hpp>
#include <ndn-cxx/util/scheduler.hpp>
#include <ndn-cxx/util/time.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/asio.hpp>
#include <boost/assert.hpp>
#include <boost/foreach.hpp>
#include <boost/core/noncopyable.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/noncopyable.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/tuple/tuple.hpp>
namespace chronosync {
using boost::noncopyable;
using std::size_t;
using boost::noncopyable;
using boost::scoped_ptr;
using std::bind;
using std::const_pointer_cast;
using std::cref;
using std::dynamic_pointer_cast;
using std::enable_shared_from_this;
using std::function;
using std::make_shared;
using std::make_tuple;
using std::ref;
using std::shared_ptr;
using std::static_pointer_cast;
using std::weak_ptr;
using ndn::Block;
using ndn::ConstBufferPtr;
using ndn::Data;
using ndn::Exclude;
using ndn::Interest;
using ndn::Name;
using ndn::security::v2::ValidationError;
using ndn::security::v2::Validator;
namespace tlv {
using namespace ndn::tlv;
} // namespace tlv
using ndn::security::Validator;
using ndn::security::ValidationError;
namespace name = ndn::name;
namespace time = ndn::time;
namespace security = ndn::security;
namespace encoding = ndn::encoding;
namespace time = ndn::time;
using namespace ndn::time_literals;
} // namespace chronosync
#endif // CHRONOSYNC_COMMON_HPP
#endif // CHRONOSYNC_DETAIL_COMMON_HPP
+4 -9
View File
@@ -1,6 +1,6 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012-2014 University of California, Los Angeles
* Copyright (c) 2012-2021 University of California, Los Angeles
*
* This file is part of ChronoSync, synchronization library for distributed realtime
* applications for NDN.
@@ -22,8 +22,8 @@
* @author Yingdi Yu <yingdi@cs.ucla.edu>
*/
#ifndef CHRONOSYNC_MI_TAG_HPP
#define CHRONOSYNC_MI_TAG_HPP
#ifndef CHRONOSYNC_DETAIL_MI_TAG_HPP
#define CHRONOSYNC_DETAIL_MI_TAG_HPP
namespace chronosync {
@@ -40,11 +40,6 @@ struct sequenced
{
};
struct timed
{
};
} // namespace chronosync
#endif // CHRONOSYNC_MI_TAG_HPP
#endif // CHRONOSYNC_DETAIL_MI_TAG_HPP
+7 -9
View File
@@ -1,6 +1,6 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012-2014 University of California, Los Angeles
* Copyright (c) 2012-2022 University of California, Los Angeles
*
* This file is part of ChronoSync, synchronization library for distributed realtime
* applications for NDN.
@@ -19,11 +19,10 @@
* @author Yingdi Yu <yingdi@cs.ucla.edu>
*/
#ifndef CHRONOSYNC_TLV_HPP
#define CHRONOSYNC_TLV_HPP
#ifndef CHRONOSYNC_DETAIL_TLV_HPP
#define CHRONOSYNC_DETAIL_TLV_HPP
namespace chronosync {
namespace tlv {
namespace chronosync::tlv {
/**
* @brief Type value of sync reply related TLVs
@@ -32,10 +31,9 @@ namespace tlv {
enum {
SyncReply = 128, // 0x80
StateLeaf = 129, // 0x81
SeqNo = 130 // 0x82
SeqNo = 130, // 0x82
};
} // namespace tlv
} // namespace chronosync
} // namespace chronosync::tlv
#endif // CHRONOSYNC_TLV_HPP
#endif // CHRONOSYNC_DETAIL_TLV_HPP
-25
View File
@@ -1,25 +0,0 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012-2014 University of California, Los Angeles
*
* This file is part of ChronoSync, synchronization library for distributed realtime
* applications for NDN.
*
* ChronoSync 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.
*
* ChronoSync 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
* ChronoSync, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*
* @author Zhenkai Zhu <http://irl.cs.ucla.edu/~zhenkai/>
* @author Chaoyi Bian <bcy@pku.edu.cn>
* @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
* @author Yingdi Yu <yingdi@cs.ucla.edu>
*/
#include "diff-state-container.hpp"
+4 -6
View File
@@ -1,6 +1,6 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012-2017 University of California, Los Angeles
* Copyright (c) 2012-2021 University of California, Los Angeles
*
* This file is part of ChronoSync, synchronization library for distributed realtime
* applications for NDN.
@@ -25,15 +25,14 @@
#ifndef CHRONOSYNC_DIFF_STATE_CONTAINER_HPP
#define CHRONOSYNC_DIFF_STATE_CONTAINER_HPP
#include "mi-tag.hpp"
#include "detail/mi-tag.hpp"
#include "diff-state.hpp"
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/tag.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/mem_fun.hpp>
#include <boost/multi_index/tag.hpp>
namespace chronosync {
@@ -72,9 +71,8 @@ struct DiffStateContainer : public mi::multi_index_container<
DigestPtrHash,
DigestPtrEqual
>,
// sequenced index to access older/newer element (like in list)
mi::sequenced<mi::tag<sequenced> >
mi::sequenced<mi::tag<sequenced>>
>
>
{
+4 -7
View File
@@ -1,6 +1,6 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012-2017 University of California, Los Angeles
* Copyright (c) 2012-2021 University of California, Los Angeles
*
* This file is part of ChronoSync, synchronization library for distributed realtime
* applications for NDN.
@@ -25,15 +25,12 @@
#ifndef CHRONOSYNC_INTEREST_CONTAINER_HPP
#define CHRONOSYNC_INTEREST_CONTAINER_HPP
#include "common.hpp"
#include "mi-tag.hpp"
#include "diff-state-container.hpp"
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/tag.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/tag.hpp>
namespace chronosync {
@@ -50,8 +47,8 @@ public:
public:
const Interest interest;
ConstBufferPtr digest;
bool isUnknown;
ndn::EventId expirationEvent;
bool isUnknown;
ndn::scheduler::EventId expirationEvent;
};
using UnsatisfiedInterestPtr = shared_ptr<UnsatisfiedInterest>;
+5 -6
View File
@@ -1,6 +1,6 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012-2017 University of California, Los Angeles
* Copyright (c) 2012-2023 University of California, Los Angeles
*
* This file is part of ChronoSync, synchronization library for distributed realtime
* applications for NDN.
@@ -26,7 +26,7 @@
namespace chronosync {
InterestTable::InterestTable(boost::asio::io_service& io)
InterestTable::InterestTable(boost::asio::io_context& io)
: m_scheduler(io)
{
}
@@ -47,7 +47,7 @@ InterestTable::insert(const Interest& interest, ConstBufferPtr digest, bool isKn
if (entryLifetime < time::milliseconds::zero())
entryLifetime = ndn::DEFAULT_INTEREST_LIFETIME;
request->expirationEvent = m_scheduler.scheduleEvent(entryLifetime, [=] { erase(digest); });
request->expirationEvent = m_scheduler.schedule(entryLifetime, [=] { erase(digest); });
m_table.insert(request);
}
@@ -57,7 +57,7 @@ InterestTable::erase(ConstBufferPtr digest)
{
auto it = m_table.get<hashed>().find(digest);
while (it != m_table.get<hashed>().end()) {
m_scheduler.cancelEvent((*it)->expirationEvent);
(*it)->expirationEvent.cancel();
m_table.erase(it);
it = m_table.get<hashed>().find(digest);
@@ -83,9 +83,8 @@ void
InterestTable::clear()
{
for (const auto& item : m_table) {
m_scheduler.cancelEvent(item->expirationEvent);
item->expirationEvent.cancel();
}
m_table.clear();
}
+6 -8
View File
@@ -1,6 +1,6 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012-2017 University of California, Los Angeles
* Copyright (c) 2012-2023 University of California, Los Angeles
*
* This file is part of ChronoSync, synchronization library for distributed realtime
* applications for NDN.
@@ -27,10 +27,12 @@
#include "interest-container.hpp"
#include <boost/asio/io_context.hpp>
namespace chronosync {
/**
* @brief A table to keep unsatisfied Sync Interest
* @brief A table to keep unsatisfied Sync Interests.
*/
class InterestTable : noncopyable
{
@@ -38,18 +40,14 @@ public:
class Error : public std::runtime_error
{
public:
explicit
Error(const std::string& what)
: std::runtime_error(what)
{
}
using std::runtime_error::runtime_error;
};
using iterator = InterestContainer::iterator;
using const_iterator = InterestContainer::const_iterator;
explicit
InterestTable(boost::asio::io_service& io);
InterestTable(boost::asio::io_context& io);
~InterestTable();
-26
View File
@@ -1,26 +0,0 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012-2014 University of California, Los Angeles
*
* This file is part of ChronoSync, synchronization library for distributed realtime
* applications for NDN.
*
* ChronoSync 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.
*
* ChronoSync 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
* ChronoSync, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*
* @author Zhenkai Zhu <http://irl.cs.ucla.edu/~zhenkai/>
* @author Chaoyi Bian <bcy@pku.edu.cn>
* @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
* @author Yingdi Yu <yingdi@cs.ucla.edu>
*/
#include "leaf-container.hpp"
// Simply check whether LeafContainer can compile
+7 -8
View File
@@ -1,6 +1,6 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012-2017 University of California, Los Angeles
* Copyright (c) 2012-2022 University of California, Los Angeles
*
* This file is part of ChronoSync, synchronization library for distributed realtime
* applications for NDN.
@@ -25,13 +25,14 @@
#ifndef CHRONOSYNC_LEAF_CONTAINER_HPP
#define CHRONOSYNC_LEAF_CONTAINER_HPP
#include "mi-tag.hpp"
#include "detail/mi-tag.hpp"
#include "leaf.hpp"
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/mem_fun.hpp>
#include <boost/multi_index/tag.hpp>
#include <ndn-cxx/util/sha256.hpp>
@@ -41,14 +42,12 @@ namespace mi = boost::multi_index;
struct SessionNameHash
{
static_assert(ndn::util::Sha256::DIGEST_SIZE >= sizeof(std::size_t), "");
std::size_t
operator()(const Name& prefix) const
{
ConstBufferPtr buffer =
ndn::util::Sha256::computeDigest(prefix.wireEncode().wire(), prefix.wireEncode().size());
BOOST_ASSERT(buffer->size() > sizeof(std::size_t));
auto buffer = ndn::util::Sha256::computeDigest(prefix.wireEncode());
return *reinterpret_cast<const std::size_t*>(buffer->data());
}
};
+2 -2
View File
@@ -1,6 +1,6 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012-2017 University of California, Los Angeles
* Copyright (c) 2012-2021 University of California, Los Angeles
*
* This file is part of ChronoSync, synchronization library for distributed realtime
* applications for NDN.
@@ -25,7 +25,7 @@
#ifndef CHRONOSYNC_LEAF_HPP
#define CHRONOSYNC_LEAF_HPP
#include "common.hpp"
#include "detail/common.hpp"
#include <ndn-cxx/util/sha256.hpp>
-40
View File
@@ -1,40 +0,0 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012-2017 University of California, Los Angeles
*
* This file is part of ChronoSync, synchronization library for distributed realtime
* applications for NDN.
*
* ChronoSync 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.
*
* ChronoSync 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
* ChronoSync, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*
* @author Zhenkai Zhu <http://irl.cs.ucla.edu/~zhenkai/>
* @author Chaoyi Bian <bcy@pku.edu.cn>
* @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
*/
#ifndef CHRONOSYNC_LOGGER_HPP
#define CHRONOSYNC_LOGGER_HPP
#include <ndn-cxx/util/logger.hpp>
#define INIT_LOGGER(name) NDN_LOG_INIT(sync.name)
#define _LOG_ERROR(x) NDN_LOG_ERROR(x)
#define _LOG_WARN(x) NDN_LOG_WARN(x)
#define _LOG_INFO(x) NDN_LOG_INFO(x)
#define _LOG_DEBUG(x) NDN_LOG_DEBUG(x)
#define _LOG_TRACE(x) NDN_LOG_TRACE(x)
#define _LOG_FUNCTION(x) NDN_LOG_TRACE(__FUNCTION__ << "(" << x << ")")
#define _LOG_FUNCTION_NOARGS NDN_LOG_TRACE(__FUNCTION__ << "()")
#endif // CHRONOSYNC_LOGGER_HPP
+190 -339
View File
@@ -1,6 +1,6 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012-2018 University of California, Los Angeles
* Copyright (c) 2012-2023 University of California, Los Angeles
*
* This file is part of ChronoSync, synchronization library for distributed realtime
* applications for NDN.
@@ -24,43 +24,28 @@
*/
#include "logic.hpp"
#include "logger.hpp"
#include "bzip2-helper.hpp"
#include "detail/bzip2-helper.hpp"
#include <ndn-cxx/util/backports.hpp>
#include <ndn-cxx/util/exception.hpp>
#include <ndn-cxx/util/logger.hpp>
#include <ndn-cxx/util/string-helper.hpp>
INIT_LOGGER(Logic);
NDN_LOG_INIT(sync.Logic);
#define _LOG_DEBUG_ID(v) _LOG_DEBUG("Instance" << m_instanceId << ": " << v)
#define CHRONO_LOG_DBG(v) NDN_LOG_DEBUG("Instance" << m_instanceId << ": " << v)
namespace chronosync {
using ndn::EventId;
const uint8_t EMPTY_DIGEST_VALUE[] = {
const std::vector<uint8_t> EMPTY_DIGEST{
0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14,
0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24,
0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55
};
int Logic::s_instanceCounter = 0;
const ndn::Name Logic::DEFAULT_NAME;
const ndn::Name Logic::EMPTY_NAME;
const std::shared_ptr<Validator> Logic::DEFAULT_VALIDATOR;
const time::steady_clock::Duration Logic::DEFAULT_RESET_TIMER = time::seconds(0);
const time::steady_clock::Duration Logic::DEFAULT_CANCEL_RESET_TIMER = time::milliseconds(500);
const time::milliseconds Logic::DEFAULT_RESET_INTEREST_LIFETIME(1000);
const time::milliseconds Logic::DEFAULT_SYNC_INTEREST_LIFETIME(1000);
const time::milliseconds Logic::DEFAULT_SYNC_REPLY_FRESHNESS(1000);
const time::milliseconds Logic::DEFAULT_RECOVERY_INTEREST_LIFETIME(1000);
const ConstBufferPtr Logic::EMPTY_DIGEST(new ndn::Buffer(EMPTY_DIGEST_VALUE, 32));
const ndn::name::Component Logic::RESET_COMPONENT("reset");
const ndn::name::Component Logic::RECOVERY_COMPONENT("recovery");
const name::Component RESET_COMPONENT{"reset"};
const name::Component RECOVERY_COMPONENT{"recovery"};
const size_t NDNLP_EXPECTED_OVERHEAD = 20;
/**
@@ -70,22 +55,22 @@ const size_t NDNLP_EXPECTED_OVERHEAD = 20;
* The returned value can be customized using the environment variable `CHRONOSYNC_MAX_PACKET_SIZE`,
* but the returned value will be at least 500 and no more than `ndn::MAX_NDN_PACKET_SIZE`.
*/
#ifndef CHRONOSYNC_HAVE_TESTS
#ifndef CHRONOSYNC_WITH_TESTS
static
#endif // CHRONOSYNC_HAVE_TESTS
#endif // CHRONOSYNC_WITH_TESTS
size_t
getMaxPacketLimit()
{
static size_t limit = 0;
#ifndef CHRONOSYNC_HAVE_TESTS
#ifndef CHRONOSYNC_WITH_TESTS
if (limit != 0) {
return limit;
}
#endif // CHRONOSYNC_HAVE_TESTS
#endif // CHRONOSYNC_WITH_TESTS
if (getenv("CHRONOSYNC_MAX_PACKET_SIZE") != nullptr) {
try {
limit = ndn::clamp<size_t>(boost::lexical_cast<size_t>(getenv("CHRONOSYNC_MAX_PACKET_SIZE")),
limit = std::clamp<size_t>(boost::lexical_cast<size_t>(getenv("CHRONOSYNC_MAX_PACKET_SIZE")),
500, ndn::MAX_NDN_PACKET_SIZE);
}
catch (const boost::bad_lexical_cast&) {
@@ -105,8 +90,8 @@ Logic::Logic(ndn::Face& face,
const UpdateCallback& onUpdate,
const Name& defaultSigningId,
std::shared_ptr<Validator> validator,
const time::steady_clock::Duration& resetTimer,
const time::steady_clock::Duration& cancelResetTimer,
const time::steady_clock::duration& resetTimer,
const time::steady_clock::duration& cancelResetTimer,
const time::milliseconds& resetInterestLifetime,
const time::milliseconds& syncInterestLifetime,
const time::milliseconds& syncReplyFreshness,
@@ -114,14 +99,14 @@ Logic::Logic(ndn::Face& face,
const name::Component& session)
: m_face(face)
, m_syncPrefix(syncPrefix)
, m_syncReset(Name(syncPrefix).append("reset"))
, m_defaultUserPrefix(defaultUserPrefix)
, m_interestTable(m_face.getIoService())
, m_outstandingInterestId(0)
, m_interestTable(m_face.getIoContext())
, m_isInReset(false)
, m_needPeriodReset(resetTimer > time::steady_clock::Duration::zero())
, m_needPeriodReset(resetTimer > time::nanoseconds::zero())
, m_onUpdate(onUpdate)
, m_scheduler(m_face.getIoService())
, m_rng(std::random_device{}())
, m_scheduler(m_face.getIoContext())
, m_rng(ndn::random::getRandomNumberEngine())
, m_rangeUniformRandom(100, 500)
, m_reexpressionJitter(100, 500)
, m_resetTimer(resetTimer)
@@ -130,41 +115,28 @@ Logic::Logic(ndn::Face& face,
, m_syncInterestLifetime(syncInterestLifetime)
, m_syncReplyFreshness(syncReplyFreshness)
, m_recoveryInterestLifetime(recoveryInterestLifetime)
, m_validator(validator)
, m_validator(std::move(validator))
, m_instanceId(s_instanceCounter++)
{
_LOG_DEBUG_ID(">> Logic::Logic");
CHRONO_LOG_DBG(">> Logic::Logic");
addUserNode(m_defaultUserPrefix, defaultSigningId, session, false);
addUserNode(m_defaultUserPrefix, defaultSigningId, session);
m_syncReset = m_syncPrefix;
m_syncReset.append("reset");
_LOG_DEBUG_ID("Listen to: " << m_syncPrefix);
m_syncRegisteredPrefixId =
m_face.setInterestFilter(ndn::InterestFilter(m_syncPrefix).allowLoopback(false),
bind(&Logic::onSyncInterest, this, _1, _2),
bind(&Logic::onSyncRegisterFailed, this, _1, _2));
CHRONO_LOG_DBG("Listen to: " << m_syncPrefix);
m_syncRegisteredPrefix = m_face.setInterestFilter(
ndn::InterestFilter(m_syncPrefix).allowLoopback(false),
bind(&Logic::onSyncInterest, this, _1, _2),
bind(&Logic::onSyncRegisterFailed, this, _1, _2));
sendSyncInterest();
_LOG_DEBUG_ID("<< Logic::Logic");
CHRONO_LOG_DBG("<< Logic::Logic");
}
Logic::~Logic()
{
_LOG_DEBUG_ID(">> Logic::~Logic");
for (const auto& pendingInterestId : m_pendingInterests) {
m_face.removePendingInterest(pendingInterestId);
}
if (m_outstandingInterestId != nullptr) {
m_face.removePendingInterest(m_outstandingInterestId);
m_outstandingInterestId = nullptr;
}
m_face.unsetInterestFilter(m_syncRegisteredPrefixId);
CHRONO_LOG_DBG(">> Logic::~Logic");
m_interestTable.clear();
m_scheduler.cancelAllEvents();
_LOG_DEBUG_ID("<< Logic::~Logic");
CHRONO_LOG_DBG("<< Logic::~Logic");
}
void
@@ -178,20 +150,9 @@ Logic::reset(bool isOnInterest)
if (!isOnInterest)
sendResetInterest();
// reset outstanding interest name, so that data for previous interest will be dropped.
if (m_outstandingInterestId != 0) {
m_face.removePendingInterest(m_outstandingInterestId);
m_outstandingInterestId = 0;
}
sendSyncInterest();
if (static_cast<bool>(m_delayedInterestProcessingId))
m_scheduler.cancelEvent(m_delayedInterestProcessingId);
m_delayedInterestProcessingId =
m_scheduler.scheduleEvent(m_cancelResetTimer,
bind(&Logic::cancelReset, this));
m_delayedInterestProcessingId = m_scheduler.schedule(m_cancelResetTimer, [this] { cancelReset(); });
}
void
@@ -205,7 +166,7 @@ Logic::setDefaultUserPrefix(const Name& defaultUserPrefix)
}
void
Logic::addUserNode(const Name& userPrefix, const Name& signingId, const name::Component& session)
Logic::addUserNode(const Name& userPrefix, const Name& signingId, const name::Component& session, bool shouldSendReset)
{
if (userPrefix == EMPTY_NAME)
return;
@@ -220,11 +181,11 @@ Logic::addUserNode(const Name& userPrefix, const Name& signingId, const name::Co
sessionName.append(session);
}
else {
sessionName.appendNumber(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count());
sessionName.appendNumber(time::toUnixTimestamp(time::system_clock::now()).count());
}
m_nodeList[userPrefix].sessionName = sessionName;
m_nodeList[userPrefix].seqNo = 0;
reset(false);
reset(!shouldSendReset);
}
}
@@ -251,11 +212,12 @@ Logic::getSessionName(Name prefix)
{
if (prefix == EMPTY_NAME)
prefix = m_defaultUserPrefix;
auto node = m_nodeList.find(prefix);
if (node != m_nodeList.end())
return node->second.sessionName;
else
BOOST_THROW_EXCEPTION(Error("Refer to non-existent node:" + prefix.toUri()));
NDN_THROW(Error("Nonexistent node: " + prefix.toUri()));
}
const SeqNo&
@@ -263,12 +225,12 @@ Logic::getSeqNo(Name prefix)
{
if (prefix == EMPTY_NAME)
prefix = m_defaultUserPrefix;
auto node = m_nodeList.find(prefix);
if (node != m_nodeList.end())
return node->second.seqNo;
else
BOOST_THROW_EXCEPTION(Logic::Error("Refer to non-existent node:" + prefix.toUri()));
NDN_THROW(Error("Nonexistent node: " + prefix.toUri()));
}
void
@@ -286,37 +248,30 @@ Logic::updateSeqNo(const SeqNo& seqNo, const Name& updatePrefix)
auto it = m_nodeList.find(prefix);
if (it != m_nodeList.end()) {
NodeInfo& node = it->second;
_LOG_DEBUG_ID(">> Logic::updateSeqNo");
_LOG_DEBUG_ID("seqNo: " << seqNo << " m_seqNo: " << node.seqNo);
CHRONO_LOG_DBG(">> Logic::updateSeqNo");
CHRONO_LOG_DBG("seqNo: " << seqNo << " m_seqNo: " << node.seqNo);
if (seqNo < node.seqNo || seqNo == 0)
return;
node.seqNo = seqNo;
_LOG_DEBUG_ID("updateSeqNo: m_seqNo " << node.seqNo);
CHRONO_LOG_DBG("updateSeqNo: m_seqNo " << node.seqNo);
if (!m_isInReset) {
_LOG_DEBUG_ID("updateSeqNo: not in Reset ");
CHRONO_LOG_DBG("updateSeqNo: not in Reset");
ConstBufferPtr previousRoot = m_state.getRootDigest();
{
std::string hash = ndn::toHex(previousRoot->data(), previousRoot->size(), false);
_LOG_DEBUG_ID("Hash: " << hash);
}
printDigest(previousRoot);
bool isInserted = false;
bool isUpdated = false;
SeqNo oldSeq;
std::tie(isInserted, isUpdated, oldSeq) = m_state.update(node.sessionName, node.seqNo);
auto [isInserted, isUpdated, oldSeq] = m_state.update(node.sessionName, node.seqNo);
CHRONO_LOG_DBG("Insert: " << std::boolalpha << isInserted);
CHRONO_LOG_DBG("Updated: " << std::boolalpha << isUpdated);
(void)oldSeq; // silence "unused variable" warning with gcc 7
_LOG_DEBUG_ID("Insert: " << std::boolalpha << isInserted);
_LOG_DEBUG_ID("Updated: " << std::boolalpha << isUpdated);
if (isInserted || isUpdated) {
DiffStatePtr commit = make_shared<DiffState>();
commit->update(node.sessionName, node.seqNo);
commit->setRootDigest(m_state.getRootDigest());
insertToDiffLog(commit, previousRoot);
satisfyPendingSyncInterests(prefix, commit);
// formAndSendExcludeInterest(prefix, *commit, previousRoot);
}
}
}
@@ -347,12 +302,12 @@ Logic::getSessionNames() const
}
void
Logic::onSyncInterest(const Name& prefix, const Interest& interest)
Logic::onSyncInterest(const Name&, const Interest& interest)
{
_LOG_DEBUG_ID(">> Logic::onSyncInterest");
CHRONO_LOG_DBG(">> Logic::onSyncInterest");
Name name = interest.getName();
_LOG_DEBUG_ID("InterestName: " << name);
CHRONO_LOG_DBG("InterestName: " << name);
if (name.size() >= 1 && RESET_COMPONENT == name.get(-1)) {
processResetInterest(interest);
@@ -360,116 +315,111 @@ Logic::onSyncInterest(const Name& prefix, const Interest& interest)
else if (name.size() >= 2 && RECOVERY_COMPONENT == name.get(-2)) {
processRecoveryInterest(interest);
}
// Do not process exclude interests, they should be answered by CS
else if (interest.getExclude().empty()) {
else {
processSyncInterest(interest);
}
_LOG_DEBUG_ID("<< Logic::onSyncInterest");
CHRONO_LOG_DBG("<< Logic::onSyncInterest");
}
void
Logic::onSyncRegisterFailed(const Name& prefix, const std::string& msg)
{
//Sync prefix registration failed
_LOG_DEBUG_ID(">> Logic::onSyncRegisterFailed");
CHRONO_LOG_DBG(">> Logic::onSyncRegisterFailed");
}
void
Logic::onSyncData(const Interest& interest, const Data& data)
Logic::onSyncData(const Interest&, const Data& data)
{
_LOG_DEBUG_ID(">> Logic::onSyncData");
// if (static_cast<bool>(m_validator))
// m_validator->validate(data,
// bind(&Logic::onSyncDataValidated, this, _1),
// bind(&Logic::onSyncDataValidationFailed, this, _1));
// else
// onSyncDataValidated(data);
CHRONO_LOG_DBG(">> Logic::onSyncData");
if (m_validator != nullptr)
m_validator->validate(data,
bind(&Logic::onSyncDataValidated, this, _1),
bind(&Logic::onSyncDataValidationFailed, this, _1));
else
onSyncDataValidated(data);
if (interest.getExclude().empty()) {
_LOG_DEBUG_ID("First data");
onSyncDataValidated(data);
}
else {
_LOG_DEBUG_ID("Data obtained using exclude filter");
onSyncDataValidated(data, false);
}
// sendExcludeInterest(interest, data);
_LOG_DEBUG_ID("<< Logic::onSyncData");
CHRONO_LOG_DBG("<< Logic::onSyncData");
}
void
Logic::onResetData(const Interest& interest, const Data& data)
Logic::onResetData(const Interest&, const Data&)
{
// This should not happened, drop the received data.
}
void
Logic::onSyncNack(const Interest&, const ndn::lp::Nack& nack)
{
CHRONO_LOG_DBG(">> Logic::onSyncNack");
if (nack.getReason() == ndn::lp::NackReason::NO_ROUTE) {
auto after = ndn::time::milliseconds(m_reexpressionJitter(m_rng));
CHRONO_LOG_DBG("Schedule sync interest after: " << after);
m_scheduler.schedule(after, [this] { sendSyncInterest(); });
}
CHRONO_LOG_DBG("<< Logic::onSyncNack");
}
void
Logic::onSyncTimeout(const Interest& interest)
{
// It is OK. Others will handle the time out situation.
_LOG_DEBUG_ID(">> Logic::onSyncTimeout");
_LOG_DEBUG_ID("Interest: " << interest.getName());
_LOG_DEBUG_ID("<< Logic::onSyncTimeout");
CHRONO_LOG_DBG(">> Logic::onSyncTimeout");
CHRONO_LOG_DBG("Interest: " << interest.getName());
CHRONO_LOG_DBG("<< Logic::onSyncTimeout");
}
void
Logic::onSyncDataValidationFailed(const Data& data)
Logic::onSyncDataValidationFailed(const Data&)
{
// SyncReply cannot be validated.
}
void
Logic::onSyncDataValidated(const Data& data, bool firstData)
Logic::onSyncDataValidated(const Data& data)
{
Name name = data.getName();
const auto& name = data.getName();
ConstBufferPtr digest = make_shared<ndn::Buffer>(name.get(-1).value(), name.get(-1).value_size());
try {
auto contentBuffer = bzip2::decompress(reinterpret_cast<const char*>(data.getContent().value()),
data.getContent().value_size());
processSyncData(name, digest, Block(contentBuffer), firstData);
processSyncData(name, digest, Block(std::move(contentBuffer)));
}
catch (const std::ios_base::failure& error) {
_LOG_WARN("Error decompressing content of " << data.getName() << " (" << error.what() << ")");
NDN_LOG_WARN("Error decompressing content of " << name << " (" << error.what() << ")");
}
}
void
Logic::processSyncInterest(const Interest& interest, bool isTimedProcessing/*=false*/)
{
_LOG_DEBUG_ID(">> Logic::processSyncInterest");
CHRONO_LOG_DBG(">> Logic::processSyncInterest");
Name name = interest.getName();
const auto& name = interest.getName();
ConstBufferPtr digest = make_shared<ndn::Buffer>(name.get(-1).value(), name.get(-1).value_size());
ConstBufferPtr rootDigest = m_state.getRootDigest();
// If the digest of the incoming interest is the same as root digest
// Put the interest into InterestTable
if (*rootDigest == *digest) {
_LOG_DEBUG_ID("Oh, we are in the same state");
CHRONO_LOG_DBG("Oh, we are in the same state");
m_interestTable.insert(interest, digest, false);
if (!m_isInReset)
return;
if (!isTimedProcessing) {
_LOG_DEBUG_ID("Non timed processing in reset");
CHRONO_LOG_DBG("Non timed processing in reset");
// Still in reset, our own seq has not been put into state yet
// Do not hurry, some others may be also resetting and may send their reply
if (static_cast<bool>(m_delayedInterestProcessingId))
m_scheduler.cancelEvent(m_delayedInterestProcessingId);
time::milliseconds after(m_rangeUniformRandom(m_rng));
_LOG_DEBUG_ID("After: " << after);
m_delayedInterestProcessingId =
m_scheduler.scheduleEvent(after,
bind(&Logic::processSyncInterest, this, interest, true));
CHRONO_LOG_DBG("After: " << after);
m_delayedInterestProcessingId = m_scheduler.schedule(after,
[=] { processSyncInterest(interest, true); });
}
else {
_LOG_DEBUG_ID("Timed processing in reset");
CHRONO_LOG_DBG("Timed processing in reset");
// Now we can get out of reset state by putting our own stuff into m_state.
cancelReset();
}
@@ -478,58 +428,50 @@ Logic::processSyncInterest(const Interest& interest, bool isTimedProcessing/*=fa
}
// If the digest of incoming interest is an "empty" digest
if (*digest == *EMPTY_DIGEST) {
_LOG_DEBUG_ID("Poor guy, he knows nothing");
if (*digest == EMPTY_DIGEST) {
CHRONO_LOG_DBG("Poor guy, he knows nothing");
sendSyncData(m_defaultUserPrefix, name, m_state);
return;
}
DiffStateContainer::iterator stateIter = m_log.find(digest);
auto stateIter = m_log.find(digest);
// If the digest of incoming interest can be found from the log
if (stateIter != m_log.end()) {
_LOG_DEBUG_ID("It is ok, you are so close");
CHRONO_LOG_DBG("It is ok, you are so close");
sendSyncData(m_defaultUserPrefix, name, *(*stateIter)->diff());
return;
}
if (!isTimedProcessing) {
_LOG_DEBUG_ID("Let's wait, just wait for a while");
CHRONO_LOG_DBG("Let's wait, just wait for a while");
// Do not hurry, some incoming SyncReplies may help us to recognize the digest
bool doesExist = m_interestTable.has(digest);
m_interestTable.insert(interest, digest, true);
if (doesExist)
// Original comment (not sure): somebody else replied, so restart random-game timer
// YY: Get the same SyncInterest again, refresh the timer
m_scheduler.cancelEvent(m_delayedInterestProcessingId);
m_delayedInterestProcessingId =
m_scheduler.scheduleEvent(time::milliseconds(m_rangeUniformRandom(m_rng)),
bind(&Logic::processSyncInterest, this, interest, true));
m_scheduler.schedule(time::milliseconds(m_rangeUniformRandom(m_rng)),
[=] { processSyncInterest(interest, true); });
}
else {
// OK, nobody is helping us, just tell the truth.
_LOG_DEBUG_ID("OK, nobody is helping us, let us try to recover");
CHRONO_LOG_DBG("OK, nobody is helping us, let us try to recover");
m_interestTable.erase(digest);
sendRecoveryInterest(digest);
}
_LOG_DEBUG_ID("<< Logic::processSyncInterest");
CHRONO_LOG_DBG("<< Logic::processSyncInterest");
}
void
Logic::processResetInterest(const Interest& interest)
Logic::processResetInterest(const Interest&)
{
_LOG_DEBUG_ID(">> Logic::processResetInterest");
CHRONO_LOG_DBG(">> Logic::processResetInterest");
reset(true);
}
void
Logic::processSyncData(const Name& name,
ConstBufferPtr digest,
const Block& syncReplyBlock,
bool firstData)
Logic::processSyncData(const Name&, ConstBufferPtr digest, const Block& syncReply)
{
_LOG_DEBUG_ID(">> Logic::processSyncData");
CHRONO_LOG_DBG(">> Logic::processSyncData");
DiffStatePtr commit = make_shared<DiffState>();
ConstBufferPtr previousRoot = m_state.getRootDigest();
@@ -537,28 +479,22 @@ Logic::processSyncData(const Name& name,
m_interestTable.erase(digest); // Remove satisfied interest from PIT
State reply;
reply.wireDecode(syncReplyBlock);
reply.wireDecode(syncReply);
std::vector<MissingDataInfo> v;
BOOST_FOREACH(ConstLeafPtr leaf, reply.getLeaves().get<ordered>())
{
BOOST_ASSERT(leaf != 0);
for (const auto& leaf : reply.getLeaves().get<ordered>()) {
BOOST_ASSERT(leaf != nullptr);
const Name& info = leaf->getSessionName();
SeqNo seq = leaf->getSeq();
const Name& info = leaf->getSessionName();
SeqNo seq = leaf->getSeq();
bool isInserted = false;
bool isUpdated = false;
SeqNo oldSeq;
std::tie(isInserted, isUpdated, oldSeq) = m_state.update(info, seq);
if (isInserted || isUpdated) {
commit->update(info, seq);
oldSeq++;
MissingDataInfo mdi = {info, oldSeq, seq};
v.push_back(mdi);
}
auto [isInserted, isUpdated, oldSeq] = m_state.update(info, seq);
if (isInserted || isUpdated) {
commit->update(info, seq);
oldSeq++;
v.push_back({info, oldSeq, seq});
}
}
if (!v.empty()) {
m_onUpdate(v);
@@ -567,34 +503,29 @@ Logic::processSyncData(const Name& name,
insertToDiffLog(commit, previousRoot);
}
else {
_LOG_DEBUG_ID("What? nothing new");
CHRONO_LOG_DBG("What? nothing new");
}
}
catch (const State::Error&) {
_LOG_DEBUG_ID("Something really fishy happened during state decoding");
// Something really fishy happened during state decoding;
CHRONO_LOG_DBG("Something really fishy happened during state decoding");
commit.reset();
return;
}
if (static_cast<bool>(commit) && !commit->getLeaves().empty() && firstData) {
if (static_cast<bool>(commit) && !commit->getLeaves().empty()) {
// state changed and it is safe to express a new interest
time::steady_clock::Duration after = time::milliseconds(m_reexpressionJitter(m_rng));
_LOG_DEBUG_ID("Reschedule sync interest after: " << after);
EventId eventId = m_scheduler.scheduleEvent(after,
bind(&Logic::sendSyncInterest, this));
m_scheduler.cancelEvent(m_reexpressingInterestId);
m_reexpressingInterestId = eventId;
auto after = time::milliseconds(m_reexpressionJitter(m_rng));
CHRONO_LOG_DBG("Reschedule sync interest after: " << after);
m_reexpressingInterestId = m_scheduler.schedule(after, [this] { sendSyncInterest(); });
}
}
void
Logic::satisfyPendingSyncInterests(const Name& updatedPrefix, ConstDiffStatePtr commit)
{
_LOG_DEBUG_ID(">> Logic::satisfyPendingSyncInterests");
CHRONO_LOG_DBG(">> Logic::satisfyPendingSyncInterests");
try {
_LOG_DEBUG_ID("InterestTable size: " << m_interestTable.size());
CHRONO_LOG_DBG("InterestTable size: " << m_interestTable.size());
auto it = m_interestTable.begin();
while (it != m_interestTable.end()) {
ConstUnsatisfiedInterestPtr request = *it;
@@ -609,13 +540,13 @@ Logic::satisfyPendingSyncInterests(const Name& updatedPrefix, ConstDiffStatePtr
catch (const InterestTable::Error&) {
// ok. not really an error
}
_LOG_DEBUG_ID("<< Logic::satisfyPendingSyncInterests");
CHRONO_LOG_DBG("<< Logic::satisfyPendingSyncInterests");
}
void
Logic::insertToDiffLog(DiffStatePtr commit, ConstBufferPtr previousRoot)
{
_LOG_DEBUG_ID(">> Logic::insertToDiffLog");
CHRONO_LOG_DBG(">> Logic::insertToDiffLog");
// Connect to the history
if (!m_log.empty())
(*m_log.find(previousRoot))->setNext(commit);
@@ -623,77 +554,66 @@ Logic::insertToDiffLog(DiffStatePtr commit, ConstBufferPtr previousRoot)
// Insert the commit
m_log.erase(commit->getRootDigest());
m_log.insert(commit);
_LOG_DEBUG_ID("<< Logic::insertToDiffLog");
CHRONO_LOG_DBG("<< Logic::insertToDiffLog");
}
void
Logic::sendResetInterest()
{
_LOG_DEBUG_ID(">> Logic::sendResetInterest");
CHRONO_LOG_DBG(">> Logic::sendResetInterest");
if (m_needPeriodReset) {
_LOG_DEBUG_ID("Need Period Reset");
_LOG_DEBUG_ID("ResetTimer: " << m_resetTimer);
CHRONO_LOG_DBG("Need Period Reset");
CHRONO_LOG_DBG("ResetTimer: " << m_resetTimer);
EventId eventId =
m_scheduler.scheduleEvent(m_resetTimer + ndn::time::milliseconds(m_reexpressionJitter(m_rng)),
bind(&Logic::sendResetInterest, this));
m_scheduler.cancelEvent(m_resetInterestId);
m_resetInterestId = eventId;
m_resetInterestId = m_scheduler.schedule(m_resetTimer + time::milliseconds(m_reexpressionJitter(m_rng)),
[this] { sendResetInterest(); });
}
Interest interest(m_syncReset);
interest.setMustBeFresh(true);
interest.setInterestLifetime(m_resetInterestLifetime);
const ndn::PendingInterestId* pendingInterestId = m_face.expressInterest(interest,
// Assigning to m_pendingResetInterest cancels the previous reset Interest.
// This is harmless since no Data is expected.
m_pendingResetInterest = m_face.expressInterest(interest,
bind(&Logic::onResetData, this, _1, _2),
bind(&Logic::onSyncTimeout, this, _1), // Nack
bind(&Logic::onSyncTimeout, this, _1));
m_scheduler.scheduleEvent(m_resetInterestLifetime + ndn::time::milliseconds(5),
[pendingInterestId, this] {
cleanupPendingInterest(pendingInterestId);
});
m_pendingInterests.push_back(pendingInterestId);
_LOG_DEBUG_ID("<< Logic::sendResetInterest");
CHRONO_LOG_DBG("<< Logic::sendResetInterest");
}
void
Logic::sendSyncInterest()
{
_LOG_DEBUG_ID(">> Logic::sendSyncInterest");
CHRONO_LOG_DBG(">> Logic::sendSyncInterest");
Name interestName;
interestName.append(m_syncPrefix)
.append(ndn::name::Component(*m_state.getRootDigest()));
.append(name::Component(*m_state.getRootDigest()));
m_outstandingInterestName = interestName;
m_pendingSyncInterestName = interestName;
#ifdef _DEBUG
printDigest(m_state.getRootDigest());
#endif
EventId eventId =
m_scheduler.scheduleEvent(m_syncInterestLifetime / 2 +
ndn::time::milliseconds(m_reexpressionJitter(m_rng)),
bind(&Logic::sendSyncInterest, this));
m_scheduler.cancelEvent(m_reexpressingInterestId);
m_reexpressingInterestId = eventId;
m_reexpressingInterestId = m_scheduler.schedule(m_syncInterestLifetime / 2 +
time::milliseconds(m_reexpressionJitter(m_rng)),
[this] { sendSyncInterest(); });
Interest interest(interestName);
interest.setMustBeFresh(true);
interest.setCanBePrefix(true);
interest.setInterestLifetime(m_syncInterestLifetime);
if (m_outstandingInterestId != nullptr) {
m_face.removePendingInterest(m_outstandingInterestId);
m_outstandingInterestId = nullptr;
}
m_outstandingInterestId = m_face.expressInterest(interest,
bind(&Logic::onSyncData, this, _1, _2),
bind(&Logic::onSyncTimeout, this, _1), // Nack
bind(&Logic::onSyncTimeout, this, _1));
m_pendingSyncInterest = m_face.expressInterest(interest,
bind(&Logic::onSyncData, this, _1, _2),
bind(&Logic::onSyncNack, this, _1, _2),
bind(&Logic::onSyncTimeout, this, _1));
_LOG_DEBUG_ID("Send interest: " << interest.getName());
_LOG_DEBUG_ID("<< Logic::sendSyncInterest");
CHRONO_LOG_DBG("Send interest: " << interest.getName());
CHRONO_LOG_DBG("<< Logic::sendSyncInterest");
}
void
@@ -702,18 +622,18 @@ Logic::trimState(State& partialState, const State& state, size_t nExcludedStates
partialState.reset();
std::vector<ConstLeafPtr> leaves;
for (const ConstLeafPtr& leaf : state.getLeaves()) {
for (const auto& leaf : state.getLeaves()) {
leaves.push_back(leaf);
}
std::shuffle(leaves.begin(), leaves.end(), m_rng);
size_t statesToEncode = leaves.size() - std::min(leaves.size() - 1, nExcludedStates);
for (const auto& constLeafPtr : leaves) {
for (const auto& leaf : leaves) {
if (statesToEncode == 0) {
break;
}
partialState.update(constLeafPtr->getSessionName(), constLeafPtr->getSeq());
partialState.update(leaf->getSessionName(), leaf->getSeq());
--statesToEncode;
}
}
@@ -725,7 +645,7 @@ Logic::encodeSyncReply(const Name& nodePrefix, const Name& name, const State& st
syncReply.setFreshnessPeriod(m_syncReplyFreshness);
auto finalizeReply = [this, &nodePrefix, &syncReply] (const State& state) {
auto contentBuffer = bzip2::compress(reinterpret_cast<const char*>(state.wireEncode().wire()),
auto contentBuffer = bzip2::compress(reinterpret_cast<const char*>(state.wireEncode().data()),
state.wireEncode().size());
syncReply.setContent(contentBuffer);
@@ -741,13 +661,14 @@ Logic::encodeSyncReply(const Name& nodePrefix, const Name& name, const State& st
while (syncReply.wireEncode().size() > getMaxPacketLimit() - NDNLP_EXPECTED_OVERHEAD) {
if (nExcludedStates == 1) {
// To show this debug message only once
_LOG_DEBUG("Sync reply size exceeded maximum packet limit (" << (getMaxPacketLimit() - NDNLP_EXPECTED_OVERHEAD) << ")");
NDN_LOG_DEBUG("Sync reply size exceeded maximum packet limit ("
<< (getMaxPacketLimit() - NDNLP_EXPECTED_OVERHEAD) << ")");
}
State partialState;
trimState(partialState, state, nExcludedStates);
finalizeReply(partialState);
BOOST_ASSERT(state.getLeaves().size() != 0);
BOOST_ASSERT(!state.getLeaves().empty());
nExcludedStates *= 2;
}
@@ -757,35 +678,30 @@ Logic::encodeSyncReply(const Name& nodePrefix, const Name& name, const State& st
void
Logic::sendSyncData(const Name& nodePrefix, const Name& name, const State& state)
{
_LOG_DEBUG_ID(">> Logic::sendSyncData");
CHRONO_LOG_DBG(">> Logic::sendSyncData");
if (m_nodeList.find(nodePrefix) == m_nodeList.end())
return;
m_face.put(encodeSyncReply(nodePrefix, name, state));
// checking if our own interest got satisfied
if (m_outstandingInterestName == name) {
if (m_pendingSyncInterestName == name) {
// remove outstanding interest
if (m_outstandingInterestId != 0) {
m_face.removePendingInterest(m_outstandingInterestId);
m_outstandingInterestId = 0;
}
m_pendingSyncInterest.cancel();
// re-schedule sending Sync interest
time::milliseconds after(m_reexpressionJitter(m_rng));
_LOG_DEBUG_ID("Satisfy our own interest");
_LOG_DEBUG_ID("Reschedule sync interest after " << after);
EventId eventId = m_scheduler.scheduleEvent(after, bind(&Logic::sendSyncInterest, this));
m_scheduler.cancelEvent(m_reexpressingInterestId);
m_reexpressingInterestId = eventId;
CHRONO_LOG_DBG("Satisfy our own interest");
CHRONO_LOG_DBG("Reschedule sync interest after " << after);
m_reexpressingInterestId = m_scheduler.schedule(after, [this] { sendSyncInterest(); });
}
_LOG_DEBUG_ID("<< Logic::sendSyncData");
CHRONO_LOG_DBG("<< Logic::sendSyncData");
}
void
Logic::cancelReset()
{
_LOG_DEBUG_ID(">> Logic::cancelReset");
CHRONO_LOG_DBG(">> Logic::cancelReset");
if (!m_isInReset)
return;
@@ -793,138 +709,73 @@ Logic::cancelReset()
for (const auto& node : m_nodeList) {
updateSeqNo(node.second.seqNo, node.first);
}
_LOG_DEBUG_ID("<< Logic::cancelReset");
CHRONO_LOG_DBG("<< Logic::cancelReset");
}
void
Logic::printDigest(ConstBufferPtr digest)
Logic::printDigest(const ConstBufferPtr& digest) const
{
std::string hash = ndn::toHex(digest->data(), digest->size(), false);
_LOG_DEBUG_ID("Hash: " << hash);
CHRONO_LOG_DBG("Hash: " << ndn::toHex(*digest, false));
}
void
Logic::sendRecoveryInterest(ConstBufferPtr digest)
{
_LOG_DEBUG_ID(">> Logic::sendRecoveryInterest");
CHRONO_LOG_DBG(">> Logic::sendRecoveryInterest");
Name interestName;
interestName.append(m_syncPrefix)
.append(RECOVERY_COMPONENT)
.append(ndn::name::Component(*digest));
.append(name::Component(*digest));
Interest interest(interestName);
interest.setMustBeFresh(true);
interest.setCanBePrefix(true);
interest.setInterestLifetime(m_recoveryInterestLifetime);
const ndn::PendingInterestId* pendingInterestId = m_face.expressInterest(interest,
m_pendingRecoveryInterests[interestName[-1].toUri()] = m_face.expressInterest(interest,
bind(&Logic::onRecoveryData, this, _1, _2),
bind(&Logic::onRecoveryTimeout, this, _1), // Nack
bind(&Logic::onRecoveryTimeout, this, _1));
m_scheduler.scheduleEvent(m_recoveryInterestLifetime + ndn::time::milliseconds(5),
[pendingInterestId, this] {
cleanupPendingInterest(pendingInterestId);
});
m_pendingInterests.push_back(pendingInterestId);
_LOG_DEBUG_ID("interest: " << interest.getName());
_LOG_DEBUG_ID("<< Logic::sendRecoveryInterest");
CHRONO_LOG_DBG("interest: " << interest.getName());
CHRONO_LOG_DBG("<< Logic::sendRecoveryInterest");
}
void
Logic::processRecoveryInterest(const Interest& interest)
{
_LOG_DEBUG_ID(">> Logic::processRecoveryInterest");
CHRONO_LOG_DBG(">> Logic::processRecoveryInterest");
Name name = interest.getName();
const auto& name = interest.getName();
ConstBufferPtr digest = make_shared<ndn::Buffer>(name.get(-1).value(), name.get(-1).value_size());
ConstBufferPtr rootDigest = m_state.getRootDigest();
DiffStateContainer::iterator stateIter = m_log.find(digest);
if (stateIter != m_log.end() || *digest == *EMPTY_DIGEST || *rootDigest == *digest) {
_LOG_DEBUG_ID("I can help you recover");
auto stateIter = m_log.find(digest);
if (stateIter != m_log.end() || *digest == EMPTY_DIGEST || *rootDigest == *digest) {
CHRONO_LOG_DBG("I can help you recover");
sendSyncData(m_defaultUserPrefix, name, m_state);
return;
}
_LOG_DEBUG_ID("<< Logic::processRecoveryInterest");
CHRONO_LOG_DBG("<< Logic::processRecoveryInterest");
}
void
Logic::onRecoveryData(const Interest& interest, const Data& data)
{
_LOG_DEBUG_ID(">> Logic::onRecoveryData");
CHRONO_LOG_DBG(">> Logic::onRecoveryData");
m_pendingRecoveryInterests.erase(interest.getName()[-1].toUri());
onSyncDataValidated(data);
_LOG_DEBUG_ID("<< Logic::onRecoveryData");
CHRONO_LOG_DBG("<< Logic::onRecoveryData");
}
void
Logic::onRecoveryTimeout(const Interest& interest)
{
_LOG_DEBUG_ID(">> Logic::onRecoveryTimeout");
_LOG_DEBUG_ID("Interest: " << interest.getName());
_LOG_DEBUG_ID("<< Logic::onRecoveryTimeout");
CHRONO_LOG_DBG(">> Logic::onRecoveryTimeout");
m_pendingRecoveryInterests.erase(interest.getName()[-1].toUri());
CHRONO_LOG_DBG("Interest: " << interest.getName());
CHRONO_LOG_DBG("<< Logic::onRecoveryTimeout");
}
void
Logic::cleanupPendingInterest(const ndn::PendingInterestId* pendingInterestId)
{
auto itr = std::find(m_pendingInterests.begin(), m_pendingInterests.end(), pendingInterestId);
if (itr != m_pendingInterests.end()) {
m_pendingInterests.erase(itr);
}
}
// void
// Logic::sendExcludeInterest(const Interest& interest, const Data& data)
// {
// _LOG_DEBUG_ID(">> Logic::sendExcludeInterest");
// Name interestName = interest.getName();
// Interest excludeInterest(interestName);
// Exclude exclude = interest.getExclude();
// exclude.excludeOne(data.getFullName().get(-1));
// excludeInterest.setExclude(exclude);
// excludeInterest.setMustBeFresh(true);
// excludeInterest.setInterestLifetime(m_syncInterestLifetime);
// if (excludeInterest.wireEncode().size() > ndn::MAX_NDN_PACKET_SIZE) {
// return;
// }
// m_face.expressInterest(excludeInterest,
// bind(&Logic::onSyncData, this, _1, _2),
// bind(&Logic::onSyncTimeout, this, _1), // Nack
// bind(&Logic::onSyncTimeout, this, _1));
// _LOG_DEBUG_ID("Send interest: " << excludeInterest.getName());
// _LOG_DEBUG_ID("<< Logic::sendExcludeInterest");
// }
// void
// Logic::formAndSendExcludeInterest(const Name& nodePrefix, const State& commit, ConstBufferPtr previousRoot)
// {
// _LOG_DEBUG_ID(">> Logic::formAndSendExcludeInterest");
// Name interestName;
// interestName.append(m_syncPrefix)
// .append(ndn::name::Component(*previousRoot));
// Interest interest(interestName);
// Data data(interestName);
// data.setContent(commit.wireEncode());
// data.setFreshnessPeriod(m_syncReplyFreshness);
// if (m_nodeList.find(nodePrefix) == m_nodeList.end())
// return;
// if (m_nodeList[nodePrefix].signingId.empty())
// m_keyChain.sign(data);
// else
// m_keyChain.sign(data, security::signingByIdentity(m_nodeList[nodePrefix].signingId));
// sendExcludeInterest(interest, data);
// _LOG_DEBUG_ID("<< Logic::formAndSendExcludeInterest");
// }
} // namespace chronosync
+53 -88
View File
@@ -1,6 +1,6 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012-2018 University of California, Los Angeles
* Copyright (c) 2012-2022 University of California, Los Angeles
*
* This file is part of ChronoSync, synchronization library for distributed realtime
* applications for NDN.
@@ -29,14 +29,8 @@
#include "diff-state-container.hpp"
#include "interest-table.hpp"
#include <boost/archive/iterators/dataflow_exception.hpp>
#include <boost/archive/iterators/transform_width.hpp>
#include <boost/assert.hpp>
#include <boost/iterator/transform_iterator.hpp>
#include <boost/throw_exception.hpp>
#include <ndn-cxx/util/random.hpp>
#include <memory>
#include <random>
#include <unordered_map>
namespace chronosync {
@@ -76,7 +70,7 @@ public:
* The parameter is a set of MissingDataInfo, of which each corresponds to
* a session that has changed its state.
*/
using UpdateCallback = function<void(const std::vector<MissingDataInfo>&)>;
using UpdateCallback = std::function<void(const std::vector<MissingDataInfo>&)>;
/**
* @brief Logic of ChronoSync
@@ -87,20 +81,18 @@ public:
class Error : public std::runtime_error
{
public:
explicit
Error(const std::string& what)
: std::runtime_error(what)
{
}
using std::runtime_error::runtime_error;
};
public:
static const time::steady_clock::Duration DEFAULT_RESET_TIMER;
static const time::steady_clock::Duration DEFAULT_CANCEL_RESET_TIMER;
static const time::milliseconds DEFAULT_RESET_INTEREST_LIFETIME;
static const time::milliseconds DEFAULT_SYNC_INTEREST_LIFETIME;
static const time::milliseconds DEFAULT_SYNC_REPLY_FRESHNESS;
static const time::milliseconds DEFAULT_RECOVERY_INTEREST_LIFETIME;
static inline const Name EMPTY_NAME;
static inline const Name DEFAULT_NAME;
static inline const std::shared_ptr<Validator> DEFAULT_VALIDATOR;
static constexpr time::steady_clock::duration DEFAULT_RESET_TIMER = 0_ms;
static constexpr time::steady_clock::duration DEFAULT_CANCEL_RESET_TIMER = 500_ms;
static constexpr time::milliseconds DEFAULT_RESET_INTEREST_LIFETIME = 1_s;
static constexpr time::milliseconds DEFAULT_SYNC_INTEREST_LIFETIME = 1_s;
static constexpr time::milliseconds DEFAULT_SYNC_REPLY_FRESHNESS = 1_s;
static constexpr time::milliseconds DEFAULT_RECOVERY_INTEREST_LIFETIME = 1_s;
/**
* @brief Constructor
@@ -125,8 +117,8 @@ public:
const UpdateCallback& onUpdate,
const Name& defaultSigningId = DEFAULT_NAME,
std::shared_ptr<Validator> validator = DEFAULT_VALIDATOR,
const time::steady_clock::Duration& resetTimer = DEFAULT_RESET_TIMER,
const time::steady_clock::Duration& cancelResetTimer = DEFAULT_CANCEL_RESET_TIMER,
const time::steady_clock::duration& resetTimer = DEFAULT_RESET_TIMER,
const time::steady_clock::duration& cancelResetTimer = DEFAULT_CANCEL_RESET_TIMER,
const time::milliseconds& resetInterestLifetime = DEFAULT_RESET_INTEREST_LIFETIME,
const time::milliseconds& syncInterestLifetime = DEFAULT_SYNC_INTEREST_LIFETIME,
const time::milliseconds& syncReplyFreshness = DEFAULT_SYNC_REPLY_FRESHNESS,
@@ -168,10 +160,11 @@ public:
* @param userPrefix prefix of the added node
* @param signingId signing Id of the added node
* @param session manually defined session ID
* @param shouldSendReset enable/disable sending the reset interest
*/
void
addUserNode(const Name& userPrefix, const Name& signingId = DEFAULT_NAME,
const name::Component& session = name::Component());
const name::Component& session = name::Component(), bool shouldSendReset = true);
/// @brief remove the node from the local session
void
@@ -289,6 +282,18 @@ private:
void
onResetData(const Interest& interest, const Data& data);
/**
* @brief Callback to handle Sync Interest Nack
*
* This method checks whether the Nack is of type NoRoute
* and schedules a sync interest in m_reexpressionJitter
*
* @param interest The sync interest for which the Nack happened
* @param nack The incoming Nack
*/
void
onSyncNack(const Interest& interest, const ndn::lp::Nack& nack);
/**
* @brief Callback to handle Sync Interest timeout.
*
@@ -315,10 +320,9 @@ private:
* This method simply passes the valid reply to processSyncData.
*
* @param data The valid Sync Reply.
* @param firstData Whether the data is new or that obtained using exclude filter
*/
void
onSyncDataValidated(const Data& data, bool firstData = true);
onSyncDataValidated(const Data& data);
/**
* @brief Process normal Sync Interest
@@ -352,26 +356,21 @@ private:
* This method extracts state update information from Sync Reply and applies
* it to the Sync Tree and re-express Sync Interest.
*
* @param name The data name of the Sync Reply.
* @param digest The digest in the data name.
* @param syncReplyBlock The content of the Sync Reply.
* @param firstData Whether the data is new or obtained using exclude filter
* @param name The data name of the Sync Reply.
* @param digest The digest in the data name.
* @param syncReply The content of the Sync Reply.
*/
void
processSyncData(const Name& name,
ConstBufferPtr digest,
const Block& syncReplyBlock,
bool firstData);
processSyncData(const Name& name, ConstBufferPtr digest, const Block& syncReply);
/**
* @brief Insert state diff into log
*
* @param diff The diff .
* @param diff The diff.
* @param previousRoot The root digest before state changes.
*/
void
insertToDiffLog(DiffStatePtr diff,
ConstBufferPtr previousRoot);
insertToDiffLog(DiffStatePtr diff, ConstBufferPtr previousRoot);
/**
* @brief Reply to all pending Sync Interests with a particular commit (or diff)
@@ -403,7 +402,7 @@ private:
cancelReset();
void
printDigest(ConstBufferPtr digest);
printDigest(const ConstBufferPtr& digest) const;
/**
* @brief Helper method to send Recovery Interest
@@ -446,48 +445,13 @@ private:
void
onRecoveryTimeout(const Interest& interest);
// /**
// * @brief Helper method to send Exclude Interest
// *
// * @param interest The interest whose exclude filter will be augmented
// * @param data The data whose implicit digest will be inserted into exclude filter
// */
// void
// sendExcludeInterest(const Interest& interest, const Data& data);
// /**
// * @brief Helper method to form the exclude Interest and calls sendExcludeInterest
// *
// * @param interest The interest whose exclude filter will be augmented
// * @param nodePrefix The prefix of the sender node
// * @param commit The commit whose contents will be used to obtain the implicit
// digest to be excluded
// * @param previousRoot The digest to be included in the interest
// */
// void
// formAndSendExcludeInterest(const Name& nodePrefix,
// const State& commit,
// ConstBufferPtr previousRoot);
void
cleanupPendingInterest(const ndn::PendingInterestId* pendingInterestId);
public:
static const ndn::Name DEFAULT_NAME;
static const ndn::Name EMPTY_NAME;
static const std::shared_ptr<Validator> DEFAULT_VALIDATOR;
private:
using NodeList = std::unordered_map<ndn::Name, NodeInfo>;
static const ConstBufferPtr EMPTY_DIGEST;
static const ndn::name::Component RESET_COMPONENT;
static const ndn::name::Component RECOVERY_COMPONENT;
using NodeList = std::unordered_map<Name, NodeInfo>;
// Communication
ndn::Face& m_face;
Name m_syncPrefix;
const ndn::RegisteredPrefixId* m_syncRegisteredPrefixId;
ndn::ScopedRegisteredPrefixHandle m_syncRegisteredPrefix;
Name m_syncReset;
Name m_defaultUserPrefix;
@@ -496,9 +460,10 @@ private:
State m_state;
DiffStateContainer m_log;
InterestTable m_interestTable;
Name m_outstandingInterestName;
const ndn::PendingInterestId* m_outstandingInterestId;
std::vector<const ndn::PendingInterestId*> m_pendingInterests;
Name m_pendingSyncInterestName;
ndn::ScopedPendingInterestHandle m_pendingSyncInterest;
ndn::ScopedPendingInterestHandle m_pendingResetInterest;
std::map<std::string, ndn::ScopedPendingInterestHandle> m_pendingRecoveryInterests;
bool m_isInReset;
bool m_needPeriodReset;
@@ -507,18 +472,18 @@ private:
// Event
ndn::Scheduler m_scheduler;
ndn::EventId m_delayedInterestProcessingId;
ndn::EventId m_reexpressingInterestId;
ndn::EventId m_resetInterestId;
ndn::scheduler::ScopedEventId m_delayedInterestProcessingId;
ndn::scheduler::ScopedEventId m_reexpressingInterestId;
ndn::scheduler::ScopedEventId m_resetInterestId;
// Timer
std::mt19937 m_rng;
ndn::random::RandomNumberEngine& m_rng;
std::uniform_int_distribution<> m_rangeUniformRandom;
std::uniform_int_distribution<> m_reexpressionJitter;
/// @brief Timer to send next reset 0 for no reset
time::steady_clock::Duration m_resetTimer;
time::steady_clock::duration m_resetTimer;
/// @brief Timer to cancel reset state
time::steady_clock::Duration m_cancelResetTimer;
time::steady_clock::duration m_cancelResetTimer;
/// @brief Lifetime of reset interest
time::milliseconds m_resetInterestLifetime;
/// @brief Lifetime of sync interest
@@ -532,14 +497,14 @@ private:
ndn::KeyChain m_keyChain;
std::shared_ptr<Validator> m_validator;
int m_instanceId;
static int s_instanceCounter;
const int m_instanceId;
static inline int s_instanceCounter = 0;
};
#ifdef CHRONOSYNC_HAVE_TESTS
#ifdef CHRONOSYNC_WITH_TESTS
size_t
getMaxPacketLimit();
#endif // CHRONOSYNC_HAVE_TESTS
#endif // CHRONOSYNC_WITH_TESTS
} // namespace chronosync
+29 -32
View File
@@ -1,6 +1,6 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012-2018 University of California, Los Angeles
* Copyright (c) 2012-2022 University of California, Los Angeles
*
* This file is part of ChronoSync, synchronization library for distributed realtime
* applications for NDN.
@@ -23,16 +23,13 @@
*/
#include "socket.hpp"
#include "logger.hpp"
INIT_LOGGER(Socket);
#include <ndn-cxx/util/logger.hpp>
NDN_LOG_INIT(sync.Socket);
namespace chronosync {
const ndn::Name Socket::DEFAULT_NAME;
const ndn::Name Socket::DEFAULT_PREFIX;
const std::shared_ptr<Validator> Socket::DEFAULT_VALIDATOR;
Socket::Socket(const Name& syncPrefix,
const Name& userPrefix,
ndn::Face& face,
@@ -48,24 +45,24 @@ Socket::Socket(const Name& syncPrefix,
syncInterestLifetime, Logic::DEFAULT_SYNC_REPLY_FRESHNESS, Logic::DEFAULT_RECOVERY_INTEREST_LIFETIME,
session)
, m_signingId(signingId)
, m_validator(validator)
, m_validator(std::move(validator))
{
NDN_LOG_DEBUG(">> Socket::Socket");
if (m_userPrefix != DEFAULT_NAME)
m_registeredPrefixList[m_userPrefix] =
m_face.setInterestFilter(m_userPrefix,
bind(&Socket::onInterest, this, _1, _2),
[] (const Name& prefix, const std::string& msg) {});
[this] (auto&&... args) { onInterest(std::forward<decltype(args)>(args)...); },
[] (auto&&...) {});
NDN_LOG_DEBUG("<< Socket::Socket");
}
Socket::~Socket()
{
for(const auto& itr : m_registeredPrefixList) {
if (static_cast<bool>(itr.second))
m_face.unsetInterestFilter(itr.second);
for (auto& itr : m_registeredPrefixList) {
itr.second.unregister();
}
m_ims.erase("/");
}
void
@@ -85,8 +82,9 @@ Socket::addSyncNode(const Name& prefix, const Name& signingId, const name::Compo
m_logic.addUserNode(prefix, signingId, session);
m_registeredPrefixList[prefix] =
m_face.setInterestFilter(prefix,
bind(&Socket::onInterest, this, _1, _2),
[] (const Name& prefix, const std::string& msg) {});
[this] (auto&&... args) { onInterest(std::forward<decltype(args)>(args)...); },
[] (auto&&...) {});
NDN_LOG_DEBUG("<< addSyncNode");
}
@@ -98,8 +96,7 @@ Socket::removeSyncNode(const Name& prefix)
auto itr = m_registeredPrefixList.find(prefix);
if (itr != m_registeredPrefixList.end()) {
if (static_cast<bool>(itr->second))
m_face.unsetInterestFilter(itr->second);
itr->second.unregister();
m_registeredPrefixList.erase(itr);
}
@@ -111,21 +108,21 @@ void
Socket::publishData(const uint8_t* buf, size_t len, const ndn::time::milliseconds& freshness,
const Name& prefix)
{
publishData(ndn::encoding::makeBinaryBlock(ndn::tlv::Content, buf, len), freshness, prefix);
publishData(ndn::makeBinaryBlock(ndn::tlv::Content, {buf, len}), freshness, prefix);
}
void
Socket::publishData(const uint8_t* buf, size_t len, const ndn::time::milliseconds& freshness,
const uint64_t& seqNo, const Name& prefix)
{
publishData(ndn::encoding::makeBinaryBlock(ndn::tlv::Content, buf, len), freshness, seqNo, prefix);
publishData(ndn::makeBinaryBlock(ndn::tlv::Content, {buf, len}), freshness, seqNo, prefix);
}
void
Socket::publishData(const Block& content, const ndn::time::milliseconds& freshness,
const Name& prefix)
{
shared_ptr<Data> data = make_shared<Data>();
auto data = std::make_shared<Data>();
data->setContent(content);
data->setFreshnessPeriod(freshness);
@@ -148,7 +145,7 @@ void
Socket::publishData(const Block& content, const ndn::time::milliseconds& freshness,
const uint64_t& seqNo, const Name& prefix)
{
shared_ptr<Data> data = make_shared<Data>();
auto data = std::make_shared<Data>();
data->setContent(content);
data->setFreshnessPeriod(freshness);
@@ -179,7 +176,7 @@ Socket::fetchData(const Name& sessionName, const SeqNo& seqNo,
interest.setMustBeFresh(true);
DataValidationErrorCallback failureCallback =
bind(&Socket::onDataValidationFailed, this, _1, _2);
[this] (auto&&... args) { onDataValidationFailed(std::forward<decltype(args)>(args)...); };
m_face.expressInterest(interest,
bind(&Socket::onData, this, _1, _2, dataCallback, failureCallback),
@@ -196,7 +193,7 @@ Socket::fetchData(const Name& sessionName, const SeqNo& seqNo,
const ndn::TimeoutCallback& onTimeout,
int nRetries)
{
_LOG_DEBUG(">> Socket::fetchData");
NDN_LOG_DEBUG(">> Socket::fetchData");
Name interestName;
interestName.append(sessionName).appendNumber(seqNo);
@@ -208,24 +205,24 @@ Socket::fetchData(const Name& sessionName, const SeqNo& seqNo,
bind(onTimeout, _1), // Nack
onTimeout);
_LOG_DEBUG("<< Socket::fetchData");
NDN_LOG_DEBUG("<< Socket::fetchData");
}
void
Socket::onInterest(const Name& prefix, const Interest& interest)
Socket::onInterest(const Name&, const Interest& interest)
{
shared_ptr<const Data> data = m_ims.find(interest);
auto data = m_ims.find(interest);
if (data != nullptr) {
m_face.put(*data);
}
}
void
Socket::onData(const Interest& interest, const Data& data,
Socket::onData(const Interest&, const Data& data,
const DataValidatedCallback& onValidated,
const DataValidationErrorCallback& onFailed)
{
_LOG_DEBUG("Socket::onData");
NDN_LOG_DEBUG("Socket::onData");
if (static_cast<bool>(m_validator))
m_validator->validate(data, onValidated, onFailed);
@@ -238,7 +235,8 @@ Socket::onDataTimeout(const Interest& interest, int nRetries,
const DataValidatedCallback& onValidated,
const DataValidationErrorCallback& onFailed)
{
_LOG_DEBUG("Socket::onDataTimeout");
NDN_LOG_DEBUG("Socket::onDataTimeout");
if (nRetries <= 0)
return;
@@ -254,8 +252,7 @@ Socket::onDataTimeout(const Interest& interest, int nRetries,
}
void
Socket::onDataValidationFailed(const Data& data,
const ValidationError& error)
Socket::onDataValidationFailed(const Data&, const ValidationError&)
{
}
+8 -13
View File
@@ -1,6 +1,6 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012-2018 University of California, Los Angeles
* Copyright (c) 2012-2022 University of California, Los Angeles
*
* This file is part of ChronoSync, synchronization library for distributed realtime
* applications for NDN.
@@ -52,11 +52,7 @@ public:
class Error : public std::runtime_error
{
public:
explicit
Error(const std::string& what)
: std::runtime_error(what)
{
}
using std::runtime_error::runtime_error;
};
Socket(const Name& syncPrefix,
@@ -70,9 +66,8 @@ public:
~Socket();
using DataValidatedCallback = function<void(const Data&)>;
using DataValidationErrorCallback = function<void(const Data&, const ValidationError& error)> ;
using DataValidatedCallback = std::function<void(const Data&)>;
using DataValidationErrorCallback = std::function<void(const Data&, const ValidationError& error)> ;
/**
* @brief Add a sync node under same logic
@@ -232,12 +227,12 @@ private:
const ValidationError& error);
public:
static const ndn::Name DEFAULT_NAME;
static const ndn::Name DEFAULT_PREFIX;
static const std::shared_ptr<Validator> DEFAULT_VALIDATOR;
static inline const Name DEFAULT_NAME;
static inline const Name DEFAULT_PREFIX;
static inline const std::shared_ptr<Validator> DEFAULT_VALIDATOR;
private:
using RegisteredPrefixList = std::unordered_map<ndn::Name, const ndn::RegisteredPrefixId*>;
using RegisteredPrefixList = std::unordered_map<Name, ndn::RegisteredPrefixHandle>;
Name m_userPrefix;
ndn::Face& m_face;
+34 -46
View File
@@ -1,6 +1,6 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012-2017 University of California, Los Angeles
* Copyright (c) 2012-2022 University of California, Los Angeles
*
* This file is part of ChronoSync, synchronization library for distributed realtime
* applications for NDN.
@@ -23,38 +23,33 @@
*/
#include "state.hpp"
#include "detail/tlv.hpp"
#include <boost/range/adaptor/reversed.hpp>
#include <ndn-cxx/util/exception.hpp>
namespace chronosync {
State::~State() = default;
/**
* @brief Add or update leaf to the sync tree
*
* @param info session name of the leaf
* @param seq sequence number of the leaf
* @return 3-tuple (isInserted, isUpdated, oldSeqNo)
*/
std::tuple<bool, bool, SeqNo>
State::update(const Name& info, const SeqNo& seq)
{
m_wire.reset();
LeafContainer::iterator leaf = m_leaves.find(info);
auto leaf = m_leaves.find(info);
if (leaf == m_leaves.end()) {
m_leaves.insert(make_shared<Leaf>(info, cref(seq)));
return make_tuple(true, false, 0);
m_leaves.insert(make_shared<Leaf>(info, seq));
return {true, false, 0};
}
else {
if ((*leaf)->getSeq() == seq || seq < (*leaf)->getSeq()) {
return make_tuple(false, false, 0);
return {false, false, 0};
}
SeqNo old = (*leaf)->getSeq();
m_leaves.modify(leaf,
[=] (LeafPtr& leaf) { leaf->setSeq(seq); } );
return make_tuple(false, true, old);
m_leaves.modify(leaf, [seq] (LeafPtr& leaf) { leaf->setSeq(seq); } );
return {false, true, old};
}
}
@@ -63,16 +58,14 @@ State::getRootDigest() const
{
m_digest.reset();
BOOST_FOREACH (ConstLeafPtr leaf, m_leaves.get<ordered>())
{
BOOST_ASSERT(leaf != 0);
m_digest.update(leaf->getDigest()->data(), leaf->getDigest()->size());
}
for (const auto& leaf : m_leaves.get<ordered>()) {
BOOST_ASSERT(leaf != nullptr);
m_digest.update(*leaf->getDigest());
}
return m_digest.computeDigest();
}
void
State::reset()
{
@@ -82,30 +75,27 @@ State::reset()
State&
State::operator+=(const State& state)
{
BOOST_FOREACH (ConstLeafPtr leaf, state.getLeaves())
{
BOOST_ASSERT(leaf != 0);
update(leaf->getSessionName(), leaf->getSeq());
}
for (const auto& leaf : state.getLeaves()) {
BOOST_ASSERT(leaf != nullptr);
update(leaf->getSessionName(), leaf->getSeq());
}
return *this;
}
template<encoding::Tag T>
template<ndn::encoding::Tag T>
size_t
State::wireEncode(encoding::EncodingImpl<T>& block) const
State::wireEncode(ndn::encoding::EncodingImpl<T>& block) const
{
size_t totalLength = 0;
BOOST_REVERSE_FOREACH (ConstLeafPtr leaf, m_leaves.get<ordered>())
{
size_t entryLength = 0;
entryLength += prependNonNegativeIntegerBlock(block, tlv::SeqNo, leaf->getSeq());
entryLength += leaf->getSessionName().wireEncode(block);
entryLength += block.prependVarNumber(entryLength);
entryLength += block.prependVarNumber(tlv::StateLeaf);
totalLength += entryLength;
}
for (const auto& leaf : m_leaves.get<ordered>() | boost::adaptors::reversed) {
size_t entryLength = 0;
entryLength += prependNonNegativeIntegerBlock(block, tlv::SeqNo, leaf->getSeq());
entryLength += leaf->getSessionName().wireEncode(block);
entryLength += block.prependVarNumber(entryLength);
entryLength += block.prependVarNumber(tlv::StateLeaf);
totalLength += entryLength;
}
totalLength += block.prependVarNumber(totalLength);
totalLength += block.prependVarNumber(tlv::SyncReply);
@@ -135,28 +125,26 @@ void
State::wireDecode(const Block& wire)
{
if (!wire.hasWire())
BOOST_THROW_EXCEPTION(Error("The supplied block does not contain wire format"));
NDN_THROW(Error("The supplied block does not contain wire format"));
if (wire.type() != tlv::SyncReply)
BOOST_THROW_EXCEPTION(Error("Unexpected TLV type when decoding SyncReply: " +
boost::lexical_cast<std::string>(m_wire.type())));
NDN_THROW(Error("Unexpected TLV type when decoding SyncReply: " + std::to_string(wire.type())));
wire.parse();
m_wire = wire;
for (Block::element_const_iterator it = wire.elements_begin();
it != wire.elements_end(); it++) {
for (auto it = wire.elements_begin(); it != wire.elements_end(); it++) {
if (it->type() == tlv::StateLeaf) {
it->parse();
Block::element_const_iterator val = it->elements_begin();
auto val = it->elements_begin();
Name info(*val);
val++;
if (val != it->elements_end())
update(info, readNonNegativeInteger(*val));
else
BOOST_THROW_EXCEPTION(Error("No seqNo when decoding SyncReply"));
NDN_THROW(Error("No SeqNo when decoding SyncReply"));
}
}
}
+5 -9
View File
@@ -1,6 +1,6 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012-2017 University of California, Los Angeles
* Copyright (c) 2012-2021 University of California, Los Angeles
*
* This file is part of ChronoSync, synchronization library for distributed realtime
* applications for NDN.
@@ -26,9 +26,9 @@
#define CHRONOSYNC_STATE_HPP
#include "leaf-container.hpp"
#include "tlv.hpp"
#include <ndn-cxx/util/sha256.hpp>
#include <tuple>
namespace chronosync {
@@ -49,11 +49,7 @@ public:
class Error : public std::runtime_error
{
public:
explicit
Error(const std::string& what)
: std::runtime_error(what)
{
}
using std::runtime_error::runtime_error;
};
virtual
@@ -112,9 +108,9 @@ public:
wireDecode(const Block& wire);
protected:
template<encoding::Tag T>
template<ndn::encoding::Tag T>
size_t
wireEncode(encoding::EncodingImpl<T>& block) const;
wireEncode(ndn::encoding::EncodingImpl<T>& block) const;
protected:
LeafContainer m_leaves;
-214
View File
@@ -1,214 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2015 Regents of the University of California.
*
* Based on work by Martin Ba (http://stackoverflow.com/a/26718189)
*
* This file is distributed under the Boost Software License, Version 1.0.
* (See http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef NDN_TESTS_BOOST_MULTI_LOG_FORMATTER_HPP
#define NDN_TESTS_BOOST_MULTI_LOG_FORMATTER_HPP
#include <boost/version.hpp>
#if BOOST_VERSION >= 105900
#include <boost/test/unit_test_parameters.hpp>
#else
#include <boost/test/detail/unit_test_parameters.hpp>
#endif // BOOST_VERSION >= 105900
#include <boost/test/unit_test_log_formatter.hpp>
#include <boost/test/output/compiler_log_formatter.hpp>
#include <boost/test/output/xml_log_formatter.hpp>
namespace boost {
namespace unit_test {
namespace output {
/**
* @brief Log formatter for Boost.Test that outputs the logging to multiple formatters
*
* The log formatter is designed to output to one or multiple formatters at the same time. For
* example, one HRF formatter can output to the standard output, while XML formatter output to
* the file.
*
* Usage:
*
* // Call in init_unit_test_suite: (this will override the --log_format parameter)
* auto formatter = new boost::unit_test::output::multi_log_formatter; // same as already configured logger
*
* // Prepare and add additional logger(s)
* formatter.add(std::make_shared<boost::unit_test::output::xml_log_formatter>(),
* std::make_shared<std::ofstream>("out.xml"));
*
* boost::unit_test::unit_test_log.set_formatter(formatter);
*
* @note Calling `boost::unit_test::unit_test_log.set_stream(...)` will change the stream for
* the original logger.
*/
class multi_log_formatter : public unit_test_log_formatter
{
public:
/**
* @brief Create instance of the logger, based on the configured logger instance
*/
multi_log_formatter()
{
auto format =
#if BOOST_VERSION > 105900
runtime_config::get<output_format>(runtime_config::LOG_FORMAT);
#else
runtime_config::log_format();
#endif // BOOST_VERSION > 105900
switch (format) {
default:
#if BOOST_VERSION >= 105900
case OF_CLF:
#else
case CLF:
#endif // BOOST_VERSION >= 105900
m_loggers.push_back({std::make_shared<compiler_log_formatter>(), nullptr});
break;
#if BOOST_VERSION >= 105900
case OF_XML:
#else
case XML:
#endif // BOOST_VERSION >= 105900
m_loggers.push_back({std::make_shared<xml_log_formatter>(), nullptr});
break;
}
}
void
add(std::shared_ptr<unit_test_log_formatter> formatter, std::shared_ptr<std::ostream> os)
{
m_loggers.push_back({formatter, os});
}
// Formatter interface
void
log_start(std::ostream& os, counter_t test_cases_amount)
{
for (auto& l : m_loggers)
l.logger->log_start(l.os == nullptr ? os : *l.os, test_cases_amount);
}
void
log_finish(std::ostream& os)
{
for (auto& l : m_loggers)
l.logger->log_finish(l.os == nullptr ? os : *l.os);
}
void
log_build_info(std::ostream& os)
{
for (auto& l : m_loggers)
l.logger->log_build_info(l.os == nullptr ? os : *l.os);
}
void
test_unit_start(std::ostream& os, const test_unit& tu)
{
for (auto& l : m_loggers)
l.logger->test_unit_start(l.os == nullptr ? os : *l.os, tu);
}
void
test_unit_finish(std::ostream& os, const test_unit& tu, unsigned long elapsed)
{
for (auto& l : m_loggers)
l.logger->test_unit_finish(l.os == nullptr ? os : *l.os, tu, elapsed);
}
void
test_unit_skipped(std::ostream& os, const test_unit& tu)
{
for (auto& l : m_loggers)
l.logger->test_unit_skipped(l.os == nullptr ? os : *l.os, tu);
}
#if BOOST_VERSION >= 105900
void
log_exception_start(std::ostream& os, const log_checkpoint_data& lcd, const execution_exception& ex)
{
for (auto& l : m_loggers)
l.logger->log_exception_start(l.os == nullptr ? os : *l.os, lcd, ex);
}
void
log_exception_finish(std::ostream& os)
{
for (auto& l : m_loggers)
l.logger->log_exception_finish(l.os == nullptr ? os : *l.os);
}
#else
void
log_exception(std::ostream& os, const log_checkpoint_data& lcd, const execution_exception& ex)
{
for (auto& l : m_loggers)
l.logger->log_exception(l.os == nullptr ? os : *l.os, lcd, ex);
}
#endif // BOOST_VERSION >= 105900
void
log_entry_start(std::ostream& os, const log_entry_data& entry_data, log_entry_types let)
{
for (auto& l : m_loggers)
l.logger->log_entry_start(l.os == nullptr ? os : *l.os, entry_data, let);
}
void
log_entry_value(std::ostream& os, const_string value)
{
for (auto& l : m_loggers)
l.logger->log_entry_value(l.os == nullptr ? os : *l.os, value);
}
void
log_entry_finish(std::ostream& os)
{
for (auto& l : m_loggers)
l.logger->log_entry_finish(l.os == nullptr ? os : *l.os);
}
#if BOOST_VERSION >= 105900
void
entry_context_start(std::ostream& os, log_level level)
{
for (auto& l : m_loggers)
l.logger->entry_context_start(l.os == nullptr ? os : *l.os, level);
}
void
log_entry_context(std::ostream& os, const_string value)
{
for (auto& l : m_loggers)
l.logger->log_entry_context(l.os == nullptr ? os : *l.os, value);
}
void
entry_context_finish(std::ostream& os)
{
for (auto& l : m_loggers)
l.logger->entry_context_finish(l.os == nullptr ? os : *l.os);
}
#endif // BOOST_VERSION >= 105900
private:
struct LoggerInfo
{
std::shared_ptr<unit_test_log_formatter> logger;
std::shared_ptr<std::ostream> os;
};
std::vector<LoggerInfo> m_loggers;
};
} // namespace output
} // namespace unit_test
} // namespace boost
#endif // NDN_TESTS_BOOST_MULTI_LOG_FORMATTER_HPP
+2 -3
View File
@@ -1,6 +1,6 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012-2014 University of California, Los Angeles
* Copyright (c) 2012-2019 University of California, Los Angeles
*
* This file is part of ChronoSync, synchronization library for distributed realtime
* applications for NDN.
@@ -24,8 +24,7 @@
#pragma GCC system_header
#pragma clang system_header
#define BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>
#include <boost/concept_check.hpp>
#include <boost/test/output_test_stream.hpp>
#endif // CHRONOSYNC_TESTS_BOOST_TEST_HPP
+4 -6
View File
@@ -1,6 +1,6 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012-2017 University of California, Los Angeles
* Copyright (c) 2012-2023 University of California, Los Angeles
*
* This file is part of ChronoSync, synchronization library for distributed realtime
* applications for NDN.
@@ -22,8 +22,7 @@
#include <ndn-cxx/util/io.hpp>
#include <boost/filesystem.hpp>
namespace ndn {
namespace tests {
namespace ndn::tests {
IdentityManagementFixture::IdentityManagementFixture()
: m_keyChain("pib-memory:", "tpm-memory:")
@@ -54,7 +53,7 @@ IdentityManagementFixture::addIdentity(const Name& identity, const ndn::KeyParam
bool
IdentityManagementFixture::saveIdentityCertificate(const Name& identity, const std::string& filename, bool wantAdd)
{
ndn::security::v2::Certificate cert;
ndn::security::Certificate cert;
try {
cert = m_keyChain.getPib().getIdentity(identity).getDefaultKey().getDefaultCertificate();
}
@@ -75,5 +74,4 @@ IdentityManagementFixture::saveIdentityCertificate(const Name& identity, const s
}
}
} // namespace tests
} // namespace ndn
} // namespace ndn::tests
+7 -9
View File
@@ -1,6 +1,6 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012-2017 University of California, Los Angeles
* Copyright (c) 2012-2022 University of California, Los Angeles
*
* This file is part of ChronoSync, synchronization library for distributed realtime
* applications for NDN.
@@ -17,15 +17,14 @@
* ChronoSync, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NDN_TESTS_IDENTITY_MANAGEMENT_FIXTURE_HPP
#define NDN_TESTS_IDENTITY_MANAGEMENT_FIXTURE_HPP
#ifndef CHRONOSYNC_TESTS_IDENTITY_MANAGEMENT_FIXTURE_HPP
#define CHRONOSYNC_TESTS_IDENTITY_MANAGEMENT_FIXTURE_HPP
#include "common.hpp"
#include "detail/common.hpp"
#include "unit-test-time-fixture.hpp"
namespace ndn {
namespace tests {
namespace ndn::tests {
/** \brief a fixture that cleans up KeyChain identities and certificate files upon destruction
*/
@@ -69,7 +68,6 @@ class IdentityManagementTimeFixture : public UnitTestTimeFixture
{
};
} // namespace tests
} // namespace ndn
} // namespace ndn::tests
#endif // NDN_TESTS_IDENTITY_MANAGEMENT_FIXTURE_HPP
#endif // CHRONOSYNC_TESTS_IDENTITY_MANAGEMENT_FIXTURE_HPP
+11 -106
View File
@@ -1,116 +1,21 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2017, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012-2020 University of California, Los Angeles
*
* This file is part of ChronoSync, synchronization library for distributed realtime
* applications for NDN, originally developed as part of NFD (Named Data Networking
* Forwarding Daemon). See AUTHORS.md for complete list of NFD authors and contributors.
* applications for NDN.
*
* NFD 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.
* ChronoSync 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.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* ChronoSync 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
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
* ChronoSync, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_ALTERNATIVE_INIT_API
#include <boost/version.hpp>
#if BOOST_VERSION >= 106200
// Boost.Test v3.3 (Boost 1.62) natively supports multi-logger output
#include "boost-test.hpp"
#else
#define BOOST_TEST_NO_MAIN
#include "boost-test.hpp"
#include "boost-multi-log-formatter.hpp"
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/variables_map.hpp>
#include <boost/program_options/parsers.hpp>
#include <fstream>
#include <iostream>
static bool
init_tests()
{
init_unit_test();
namespace po = boost::program_options;
namespace ut = boost::unit_test;
po::options_description extraOptions;
std::string logger;
std::string outputFile = "-";
extraOptions.add_options()
("log_format2", po::value<std::string>(&logger), "Type of second log formatter: HRF or XML")
("log_sink2", po::value<std::string>(&outputFile)->default_value(outputFile), "Second log sink, - for stdout")
;
po::variables_map vm;
try {
po::store(po::command_line_parser(ut::framework::master_test_suite().argc,
ut::framework::master_test_suite().argv)
.options(extraOptions)
.run(),
vm);
po::notify(vm);
}
catch (const std::exception& e) {
std::cerr << "ERROR: " << e.what() << "\n"
<< extraOptions << std::endl;
return false;
}
if (vm.count("log_format2") == 0) {
// second logger is not configured
return true;
}
std::shared_ptr<ut::unit_test_log_formatter> formatter;
if (logger == "XML") {
formatter = std::make_shared<ut::output::xml_log_formatter>();
}
else if (logger == "HRF") {
formatter = std::make_shared<ut::output::compiler_log_formatter>();
}
else {
std::cerr << "ERROR: only HRF or XML log formatter can be specified" << std::endl;
return false;
}
std::shared_ptr<std::ostream> output;
if (outputFile == "-") {
output = std::shared_ptr<std::ostream>(&std::cout, std::bind([]{}));
}
else {
output = std::make_shared<std::ofstream>(outputFile.c_str());
}
auto multiFormatter = new ut::output::multi_log_formatter;
multiFormatter->add(formatter, output);
ut::unit_test_log.set_formatter(multiFormatter);
return true;
}
int
main(int argc, char* argv[])
{
return ::boost::unit_test::unit_test_main(&init_tests, argc, argv);
}
#endif // BOOST_VERSION >= 106200
#define BOOST_TEST_MODULE ChronoSync
#include "tests/boost-test.hpp"
+12 -13
View File
@@ -1,6 +1,6 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012-2017 University of California, Los Angeles
* Copyright (c) 2012-2023 University of California, Los Angeles
*
* This file is part of ChronoSync, synchronization library for distributed realtime
* applications for NDN.
@@ -17,15 +17,14 @@
* ChronoSync, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NDN_TESTS_UNIT_TESTS_UNIT_TEST_TIME_FIXTURE_HPP
#define NDN_TESTS_UNIT_TESTS_UNIT_TEST_TIME_FIXTURE_HPP
#ifndef CHRONOSYNC_TESTS_UNIT_TEST_TIME_FIXTURE_HPP
#define CHRONOSYNC_TESTS_UNIT_TEST_TIME_FIXTURE_HPP
#include <ndn-cxx/util/time-unit-test-clock.hpp>
#include <boost/asio.hpp>
#include <boost/asio/io_context.hpp>
namespace ndn {
namespace tests {
namespace ndn::tests {
class UnitTestTimeFixture
{
@@ -43,14 +42,15 @@ public:
}
void
advanceClocks(const time::nanoseconds& tick, size_t nTicks = 1)
advanceClocks(time::nanoseconds tick, size_t nTicks = 1)
{
for (size_t i = 0; i < nTicks; ++i) {
steadyClock->advance(tick);
systemClock->advance(tick);
if (io.stopped())
io.reset();
if (io.stopped()) {
io.restart();
}
io.poll();
}
}
@@ -58,10 +58,9 @@ public:
public:
shared_ptr<time::UnitTestSteadyClock> steadyClock;
shared_ptr<time::UnitTestSystemClock> systemClock;
boost::asio::io_service io;
boost::asio::io_context io;
};
} // namespace tests
} // namespace ndn
} // namespace ndn::tests
#endif // NDN_TESTS_UNIT_TESTS_UNIT_TEST_TIME_FIXTURE_HPP
#endif // CHRONOSYNC_TESTS_UNIT_TEST_TIME_FIXTURE_HPP
+3 -5
View File
@@ -1,6 +1,6 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012-2018 University of California, Los Angeles
* Copyright (c) 2012-2021 University of California, Los Angeles
*
* This file is part of ChronoSync, synchronization library for distributed realtime
* applications for NDN.
@@ -17,15 +17,13 @@
* ChronoSync, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#include "bzip2-helper.hpp"
#include "detail/bzip2-helper.hpp"
#include "boost-test.hpp"
#include "tests/boost-test.hpp"
namespace chronosync {
namespace test {
using std::tuple;
BOOST_AUTO_TEST_SUITE(TestBzip2Helper)
BOOST_AUTO_TEST_CASE(Basic)
+11 -9
View File
@@ -1,6 +1,6 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012-2018 University of California, Los Angeles
* Copyright (c) 2012-2023 University of California, Los Angeles
*
* This file is part of ChronoSync, synchronization library for distributed realtime
* applications for NDN.
@@ -19,12 +19,13 @@
#include "dummy-forwarder.hpp"
#include <boost/asio/io_service.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/post.hpp>
namespace ndn {
namespace chronosync {
DummyForwarder::DummyForwarder(boost::asio::io_service& io, KeyChain& keyChain)
DummyForwarder::DummyForwarder(boost::asio::io_context& io, KeyChain& keyChain)
: m_io(io)
, m_keyChain(keyChain)
{
@@ -33,25 +34,26 @@ DummyForwarder::DummyForwarder(boost::asio::io_service& io, KeyChain& keyChain)
Face&
DummyForwarder::addFace()
{
auto face = std::make_shared<util::DummyClientFace>(m_io, m_keyChain,
util::DummyClientFace::Options{true, true});
util::DummyClientFace* self = &*face; // to prevent memory leak
auto face = std::make_shared<DummyClientFace>(m_io, m_keyChain, DummyClientFace::Options{true, true});
DummyClientFace* self = &*face; // to prevent memory leak
face->onSendInterest.connect([this, self] (const Interest& interest) {
Interest i(interest);
for (auto& otherFace : m_faces) {
if (self == &*otherFace) {
continue;
}
m_io.post([=] { otherFace->receive(i); });
boost::asio::post(m_io, [=] { otherFace->receive(i); });
}
});
face->onSendData.connect([this, self] (const Data& data) {
Data d(data);
for (auto& otherFace : m_faces) {
if (self == &*otherFace) {
continue;
}
m_io.post([=] { otherFace->receive(d); });
boost::asio::post(m_io, [=] { otherFace->receive(d); });
}
});
@@ -61,7 +63,7 @@ DummyForwarder::addFace()
if (self == &*otherFace) {
continue;
}
m_io.post([=] { otherFace->receive(n); });
boost::asio::post(m_io, [=] { otherFace->receive(n); });
}
});
+6 -6
View File
@@ -1,6 +1,6 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012-2018 University of California, Los Angeles
* Copyright (c) 2012-2023 University of California, Los Angeles
*
* This file is part of ChronoSync, synchronization library for distributed realtime
* applications for NDN.
@@ -17,11 +17,11 @@
* ChronoSync, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#include <ndn-cxx/interest.hpp>
#include <ndn-cxx/data.hpp>
#include <ndn-cxx/interest.hpp>
#include <ndn-cxx/lp/nack.hpp>
#include <ndn-cxx/util/dummy-client-face.hpp>
#include <ndn-cxx/security/key-chain.hpp>
#include <ndn-cxx/util/dummy-client-face.hpp>
#ifndef NDN_CHRONOSYNC_UNIT_TESTS_DUMMY_FORWARDER_HPP
#define NDN_CHRONOSYNC_UNIT_TESTS_DUMMY_FORWARDER_HPP
@@ -38,7 +38,7 @@ namespace chronosync {
class DummyForwarder
{
public:
DummyForwarder(boost::asio::io_service& io, KeyChain& keyChain);
DummyForwarder(boost::asio::io_context& io, KeyChain& keyChain);
Face&
addFace();
@@ -53,9 +53,9 @@ public:
removeFaces();
private:
boost::asio::io_service& m_io;
boost::asio::io_context& m_io;
KeyChain& m_keyChain;
std::vector<shared_ptr<util::DummyClientFace>> m_faces;
std::vector<std::shared_ptr<DummyClientFace>> m_faces;
};
} // namespace chronosync
+3 -2
View File
@@ -1,6 +1,6 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012-2014 University of California, Los Angeles
* Copyright (c) 2012-2019 University of California, Los Angeles
*
* This file is part of ChronoSync, synchronization library for distributed realtime
* applications for NDN.
@@ -19,7 +19,8 @@
#include "diff-state.hpp"
#include "diff-state-container.hpp"
#include "boost-test.hpp"
#include "tests/boost-test.hpp"
namespace chronosync {
namespace test {
-25
View File
@@ -1,25 +0,0 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012-2014 University of California, Los Angeles
*
* This file is part of ChronoSync, synchronization library for distributed realtime
* applications for NDN.
*
* ChronoSync 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.
*
* ChronoSync 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
* ChronoSync, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#include "boost-test.hpp"
BOOST_AUTO_TEST_CASE(EmptyTest)
{
}
+8 -7
View File
@@ -1,6 +1,6 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012-2017 University of California, Los Angeles
* Copyright (c) 2012-2022 University of California, Los Angeles
*
* This file is part of ChronoSync, synchronization library for distributed realtime
* applications for NDN.
@@ -18,8 +18,9 @@
*/
#include "interest-table.hpp"
#include "boost-test.hpp"
#include "../unit-test-time-fixture.hpp"
#include "tests/boost-test.hpp"
#include "tests/unit-test-time-fixture.hpp"
#include <unistd.h>
@@ -31,24 +32,24 @@ class InterestTableFixture : public ndn::tests::UnitTestTimeFixture
public:
InterestTableFixture()
{
uint8_t origin[4] = {0x01, 0x02, 0x03, 0x04};
const uint8_t origin[] = {0x01, 0x02, 0x03, 0x04};
Name prefix("/test/prefix");
Name interestName1;
digest1 = ndn::util::Sha256::computeDigest(origin, 1);
digest1 = ndn::util::Sha256::computeDigest({origin, 1});
interestName1.append(prefix).append(name::Component(digest1));
interest1 = Interest(interestName1);
interest1.setInterestLifetime(time::milliseconds(100));
Name interestName2;
digest2 = ndn::util::Sha256::computeDigest(origin, 2);
digest2 = ndn::util::Sha256::computeDigest({origin, 2});
interestName2.append(prefix).append(name::Component(digest2));
interest2 = Interest(interestName2);
interest2.setInterestLifetime(time::milliseconds(100));
Name interestName3;
digest3 = ndn::util::Sha256::computeDigest(origin, 3);
digest3 = ndn::util::Sha256::computeDigest({origin, 3});
interestName3.append(prefix).append(name::Component(digest3));
interest3 = Interest(interestName3);
interest3.setInterestLifetime(time::milliseconds(100));
+4 -6
View File
@@ -1,6 +1,6 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012-2017 University of California, Los Angeles
* Copyright (c) 2012-2022 University of California, Los Angeles
*
* This file is part of ChronoSync, synchronization library for distributed realtime
* applications for NDN.
@@ -18,9 +18,10 @@
*/
#include "leaf.hpp"
#include "boost-test.hpp"
#include "leaf-container.hpp"
#include "tests/boost-test.hpp"
#include <ndn-cxx/encoding/buffer-stream.hpp>
#include <ndn-cxx/util/string-helper.hpp>
@@ -53,10 +54,7 @@ BOOST_AUTO_TEST_CASE(LeafDigest)
Name userPrefix("/test/name");
Leaf leaf(userPrefix, 1, 10);
BOOST_CHECK_NO_THROW(leaf.getDigest());
ndn::ConstBufferPtr digest = leaf.getDigest();
BOOST_CHECK_EQUAL(result, ndn::toHex(digest->data(), digest->size(), false));
BOOST_CHECK_EQUAL(result, ndn::toHex(*leaf.getDigest(), false));
}
BOOST_AUTO_TEST_CASE(Container)
+21 -28
View File
@@ -1,6 +1,6 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012-2018 University of California, Los Angeles
* Copyright (c) 2012-2023 University of California, Los Angeles
*
* This file is part of ChronoSync, synchronization library for distributed realtime
* applications for NDN.
@@ -18,36 +18,28 @@
*/
#include "logic.hpp"
#include "bzip2-helper.hpp"
#include "detail/bzip2-helper.hpp"
#include "boost-test.hpp"
#include "../identity-management-fixture.hpp"
#include "dummy-forwarder.hpp"
#include "tests/boost-test.hpp"
#include "tests/identity-management-fixture.hpp"
#include "tests/unit-tests/dummy-forwarder.hpp"
#include <ndn-cxx/util/random.hpp>
namespace chronosync {
namespace test {
using std::vector;
using ndn::chronosync::DummyForwarder;
class Handler
{
public:
Handler(ndn::Face& face,
const Name& syncPrefix,
const Name& userPrefix)
: logic(face,
syncPrefix,
userPrefix,
Handler(ndn::Face& face, const Name& syncPrefix, const Name& userPrefix)
: logic(face, syncPrefix, userPrefix,
bind(&Handler::onUpdate, this, _1))
{
}
void
onUpdate(const vector<MissingDataInfo>& v)
onUpdate(const std::vector<MissingDataInfo>& v)
{
for (size_t i = 0; i < v.size(); i++) {
update(v[i].session, v[i].high, v[i].low);
@@ -89,7 +81,7 @@ public:
Name syncPrefix;
Name userPrefix[4];
DummyForwarder fw;
ndn::chronosync::DummyForwarder fw;
// std::unique_ptr<DummyClientFace> faces[4];
shared_ptr<Handler> handler[4];
@@ -99,8 +91,8 @@ public:
BOOST_FIXTURE_TEST_SUITE(LogicTests, LogicFixture)
void
onUpdate(const vector<MissingDataInfo>& v)
static void
onUpdate(const std::vector<MissingDataInfo>&)
{
}
@@ -108,7 +100,7 @@ BOOST_AUTO_TEST_CASE(Constructor)
{
Name syncPrefix("/ndn/broadcast/sync");
Name userPrefix("/user");
ndn::util::DummyClientFace face(io, {true, true});
ndn::DummyClientFace face(io, {true, true});
BOOST_REQUIRE_NO_THROW(Logic(face, syncPrefix, userPrefix, bind(onUpdate, _1)));
}
@@ -221,7 +213,7 @@ BOOST_AUTO_TEST_CASE(RecoverConflict)
handler[1]->updateSeqNo(2);
handler[2]->updateSeqNo(4);
advanceClocks(ndn::time::milliseconds(10), 100);
advanceClocks(ndn::time::milliseconds(50), 100);
BOOST_CHECK_EQUAL(handler[0]->map[handler[1]->logic.getSessionName()], 2);
BOOST_CHECK_EQUAL(handler[0]->map[handler[2]->logic.getSessionName()], 4);
BOOST_CHECK_EQUAL(handler[1]->map[handler[2]->logic.getSessionName()], 4);
@@ -371,14 +363,14 @@ BOOST_AUTO_TEST_CASE(CancelOutstandingEvents)
systemClock->advance(ndn::time::hours(1));
BOOST_CHECK_EQUAL(io.poll(), 0); // no delayed handlers are expected
BOOST_CHECK_EQUAL(io.stopped(), true); // io_service expected to be stopped
BOOST_CHECK_EQUAL(io.stopped(), true); // io_context expected to be stopped
}
BOOST_FIXTURE_TEST_CASE(TrimState, ndn::tests::IdentityManagementTimeFixture)
{
Name syncPrefix("/ndn/broadcast/sync");
Name userPrefix("/user");
ndn::util::DummyClientFace face;
ndn::DummyClientFace face;
Logic logic(face, syncPrefix, userPrefix, bind(onUpdate, _1));
State state;
@@ -405,11 +397,11 @@ BOOST_FIXTURE_TEST_CASE(VeryLargeState, ndn::tests::IdentityManagementTimeFixtur
addIdentity("/bla");
Name syncPrefix("/ndn/broadcast/sync");
Name userPrefix("/user");
ndn::util::DummyClientFace face;
ndn::DummyClientFace face;
Logic logic(face, syncPrefix, userPrefix, bind(onUpdate, _1));
State state;
for (size_t i = 0; i < 50000 && bzip2::compress(reinterpret_cast<const char*>(state.wireEncode().wire()),
for (size_t i = 0; i < 50000 && bzip2::compress(reinterpret_cast<const char*>(state.wireEncode().data()),
state.wireEncode().size())->size() < ndn::MAX_NDN_PACKET_SIZE;
i += 10) {
Name prefix("/to/trim");
@@ -440,11 +432,12 @@ public:
{
unsetenv("CHRONOSYNC_MAX_PACKET_SIZE");
if (oldSize) {
setenv("CHRONOSYNC_MAX_PACKET_SIZE", oldSize->c_str(), 1);
setenv("CHRONOSYNC_MAX_PACKET_SIZE", oldSize->data(), 1);
}
}
private:
ndn::optional<std::string> oldSize;
std::optional<std::string> oldSize;
};
BOOST_FIXTURE_TEST_CASE(MaxPacketCustomization, MaxPacketCustomizationFixture)
@@ -454,7 +447,7 @@ BOOST_FIXTURE_TEST_CASE(MaxPacketCustomization, MaxPacketCustomizationFixture)
setenv("CHRONOSYNC_MAX_PACKET_SIZE", "1500", 1);
BOOST_CHECK_EQUAL(getMaxPacketLimit(), 1500);
setenv("CHRONOSYNC_MAX_PACKET_SIZE", ndn::to_string(ndn::MAX_NDN_PACKET_SIZE * 100).c_str(), 1);
setenv("CHRONOSYNC_MAX_PACKET_SIZE", std::to_string(ndn::MAX_NDN_PACKET_SIZE * 100).data(), 1);
BOOST_CHECK_EQUAL(getMaxPacketLimit(), ndn::MAX_NDN_PACKET_SIZE);
setenv("CHRONOSYNC_MAX_PACKET_SIZE", "1", 1);
+27 -25
View File
@@ -1,32 +1,37 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012-2023 University of California, Los Angeles
*
* This file is part of ChronoSync, synchronization library for distributed realtime
* applications for NDN.
*
* ChronoSync 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.
*
* ChronoSync 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
* ChronoSync, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#include "logic.hpp"
#include "boost-test.hpp"
#include "tests/boost-test.hpp"
namespace chronosync {
namespace test {
using std::vector;
class Handler
{
public:
Handler(ndn::Face& face,
const Name& syncPrefix,
const Name& userPrefix)
: logic(face,
syncPrefix,
userPrefix,
bind(&Handler::onUpdate, this, _1))
Handler(ndn::Face& face, const Name& syncPrefix, const Name& userPrefix)
: logic(face, syncPrefix, userPrefix, [] (auto&&...) {})
{
}
void
onUpdate(const vector<MissingDataInfo>& v)
{
}
void
updateSeqNo(const SeqNo& seqNo)
{
@@ -45,7 +50,6 @@ public:
logic.removeUserNode(prefix);
}
Logic logic;
std::map<Name, SeqNo> map;
};
@@ -53,7 +57,6 @@ public:
class MultiUserFixture
{
public:
MultiUserFixture()
: syncPrefix("/ndn/broadcast/sync")
, scheduler(io)
@@ -63,13 +66,13 @@ public:
userPrefix[1] = Name("/user1");
userPrefix[2] = Name("/user2");
face = make_shared<ndn::Face>(ref(io));
face = std::make_shared<ndn::Face>(io);
}
Name syncPrefix;
Name userPrefix[3];
boost::asio::io_service io;
boost::asio::io_context io;
shared_ptr<ndn::Face> face;
ndn::Scheduler scheduler;
shared_ptr<Handler> handler;
@@ -79,7 +82,7 @@ BOOST_FIXTURE_TEST_SUITE(MultiUserTests, MultiUserFixture)
BOOST_AUTO_TEST_CASE(ThreeUserNode)
{
handler = make_shared<Handler>(ref(*face), syncPrefix, userPrefix[0]);
handler = std::make_shared<Handler>(*face, syncPrefix, userPrefix[0]);
handler->addUserNode(userPrefix[1]);
handler->addUserNode(userPrefix[2]);
handler->removeUserNode(userPrefix[0]);
@@ -93,9 +96,8 @@ BOOST_AUTO_TEST_CASE(ThreeUserNode)
BOOST_CHECK_EQUAL(handler->logic.getSeqNo(), 2);
BOOST_REQUIRE_THROW(handler->logic.getSeqNo(userPrefix[0]), Logic::Error);
BOOST_REQUIRE_THROW(handler->logic.getSessionName(userPrefix[0]), Logic::Error);
BOOST_CHECK_THROW(handler->logic.getSeqNo(userPrefix[0]), Logic::Error);
BOOST_CHECK_THROW(handler->logic.getSessionName(userPrefix[0]), Logic::Error);
}
BOOST_AUTO_TEST_SUITE_END()
+16 -21
View File
@@ -1,6 +1,6 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012-2018 University of California, Los Angeles
* Copyright (c) 2012-2023 University of California, Los Angeles
*
* This file is part of ChronoSync, synchronization library for distributed realtime
* applications for NDN.
@@ -19,8 +19,8 @@
#include "socket.hpp"
#include "boost-test.hpp"
#include "../unit-test-time-fixture.hpp"
#include "tests/boost-test.hpp"
#include "tests/unit-test-time-fixture.hpp"
#include <ndn-cxx/util/dummy-client-face.hpp>
@@ -28,9 +28,6 @@ namespace chronosync {
namespace test {
using std::string;
using std::vector;
using std::map;
using ndn::util::DummyClientFace;
/**
* @brief Emulate an app that use the Socket class
@@ -43,14 +40,14 @@ class SocketTestApp : noncopyable
public:
SocketTestApp(const Name& syncPrefix,
const Name& userPrefix,
DummyClientFace& face,
ndn::DummyClientFace& face,
bool isNum)
: sum(0)
, socket(syncPrefix,
userPrefix,
face,
isNum ? bind(&SocketTestApp::fetchNumbers, this, _1) :
bind(&SocketTestApp::fetchAll, this, _1),
bind(&SocketTestApp::fetchAll, this, _1),
Logic::DEFAULT_NAME,
Logic::DEFAULT_VALIDATOR,
Logic::DEFAULT_SYNC_INTEREST_LIFETIME,
@@ -65,14 +62,14 @@ public:
Name dataName(dataPacket.getName());
string str2(reinterpret_cast<const char*>(dataPacket.getContent().value()),
dataPacket.getContent().value_size());
data.insert(make_pair(dataName, str2));
data.emplace(dataName, str2);
}
void
set(Name name, const char* buf, int len)
{
string str2(buf, len);
data.insert(make_pair(name, str2));
data.emplace(name, str2);
}
void
@@ -99,7 +96,7 @@ public:
}
void
fetchAll(const vector<MissingDataInfo>& v)
fetchAll(const std::vector<MissingDataInfo>& v)
{
// std::cerr << "fetchAll" << std::endl;
for (size_t i = 0; i < v.size(); i++) {
@@ -112,7 +109,7 @@ public:
}
void
fetchNumbers(const vector<MissingDataInfo>& v)
fetchNumbers(const std::vector<MissingDataInfo>& v)
{
// std::cerr << "fetchNumbers" << std::endl;
for (size_t i = 0; i < v.size(); i++) {
@@ -128,7 +125,7 @@ public:
toString()
{
string str = "\n";
for (map<Name, string>::iterator it = data.begin(); it != data.end(); ++it) {
for (auto it = data.begin(); it != data.end(); ++it) {
str += "<";
str += it->first.toUri();
str += "|";
@@ -141,7 +138,7 @@ public:
}
public:
map<ndn::Name, string> data;
std::map<Name, string> data;
uint32_t sum;
Socket socket;
};
@@ -157,9 +154,9 @@ public:
userPrefix[1] = Name("/user1");
userPrefix[2] = Name("/user2");
faces[0].reset(new DummyClientFace(io, {true, true}));
faces[1].reset(new DummyClientFace(io, {true, true}));
faces[2].reset(new DummyClientFace(io, {true, true}));
faces[0].reset(new ndn::DummyClientFace(io, {true, true}));
faces[1].reset(new ndn::DummyClientFace(io, {true, true}));
faces[2].reset(new ndn::DummyClientFace(io, {true, true}));
for (int i = 0; i < 3; i++) {
readInterestOffset[i] = 0;
@@ -196,7 +193,7 @@ public:
void
createSocket(size_t idx, bool isNum)
{
app[idx] = make_shared<SocketTestApp>(syncPrefix, userPrefix[idx], ref(*faces[idx]), isNum);
app[idx] = make_shared<SocketTestApp>(syncPrefix, userPrefix[idx], std::ref(*faces[idx]), isNum);
sessionName[idx] = app[idx]->socket.getLogic().getSessionName();
}
@@ -241,15 +238,13 @@ public:
Name userPrefix[3];
Name sessionName[3];
std::unique_ptr<DummyClientFace> faces[3];
std::unique_ptr<ndn::DummyClientFace> faces[3];
shared_ptr<SocketTestApp> app[3];
size_t readInterestOffset[3];
size_t readDataOffset[3];
};
BOOST_FIXTURE_TEST_SUITE(SocketTests, SocketFixture)
BOOST_AUTO_TEST_CASE(BasicData)
+8 -17
View File
@@ -1,6 +1,6 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012-2017 University of California, Los Angeles
* Copyright (c) 2012-2022 University of California, Los Angeles
*
* This file is part of ChronoSync, synchronization library for distributed realtime
* applications for NDN.
@@ -19,13 +19,11 @@
#include "state.hpp"
#include "boost-test.hpp"
#include "tests/boost-test.hpp"
namespace chronosync {
namespace test {
using std::tuple;
BOOST_AUTO_TEST_SUITE(StateTests)
BOOST_AUTO_TEST_CASE(Basic)
@@ -42,7 +40,7 @@ BOOST_AUTO_TEST_CASE(Basic)
BOOST_CHECK_NO_THROW(state.reset());
BOOST_CHECK_EQUAL(state.getLeaves().size(), 0);
tuple<bool, bool, SeqNo> result;
std::tuple<bool, bool, SeqNo> result;
result = state.update(info, 12);
BOOST_CHECK_EQUAL(std::get<0>(result), true);
BOOST_CHECK_EQUAL(std::get<1>(result), false);
@@ -150,17 +148,16 @@ BOOST_AUTO_TEST_CASE(DecodeEncode)
0x04
};
Block block(wire, sizeof(wire));
Block block(wire);
State state;
BOOST_REQUIRE_NO_THROW(state.wireDecode(block));
BOOST_CHECK_EQUAL(state.getLeaves().size(), 2);
LeafContainer::index<ordered>::type::iterator it = state.getLeaves().get<ordered>().begin();
auto it = state.getLeaves().get<ordered>().begin();
BOOST_CHECK_EQUAL((*it)->getSeq(), 14);
it++;
BOOST_CHECK_EQUAL((*it)->getSeq(), 4);
State state2;
Name info1("/test/name");
@@ -171,15 +168,9 @@ BOOST_AUTO_TEST_CASE(DecodeEncode)
info2.appendNumber(1);
state2.update(info2, 4);
BOOST_REQUIRE_NO_THROW(state2.wireEncode());
Block block2 = state2.wireEncode();
BOOST_CHECK_EQUAL_COLLECTIONS(block.wire(),
block.wire() + block.size(),
block2.wire(),
block2.wire() + block2.size());
BOOST_CHECK(*state.getRootDigest() == *state2.getRootDigest());
BOOST_TEST(block == block2, boost::test_tools::per_element());
BOOST_TEST(*state.getRootDigest() == *state2.getRootDigest(), boost::test_tools::per_element());
}
BOOST_AUTO_TEST_CASE(Combine)
@@ -210,7 +201,7 @@ BOOST_AUTO_TEST_CASE(Combine)
BOOST_CHECK_EQUAL(state1.getLeaves().size(), 2);
BOOST_CHECK_EQUAL(state2.getLeaves().size(), 3);
LeafContainer::index<ordered>::type::iterator it = state2.getLeaves().get<ordered>().begin();
auto it = state2.getLeaves().get<ordered>().begin();
BOOST_CHECK_EQUAL((*it)->getSeq(), 4);
it++;
BOOST_CHECK_EQUAL((*it)->getSeq(), 15);
+4 -20
View File
@@ -1,28 +1,12 @@
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
from waflib import Utils
top = '..'
def build(bld):
bld.objects(
target='tests-main',
source='main.cpp',
use='ChronoSync',
defines=['BOOST_TEST_MODULE=ChronoSync'])
bld.program(
target="../unit-tests",
target=f'{top}/unit-tests',
name='unit-tests',
source=bld.path.ant_glob(['unit-tests/**/*.cpp', 'identity-management-fixture.cpp']),
use='ChronoSync tests-main',
includes=['.'],
source=bld.path.ant_glob('**/*.cpp'),
use='BOOST_TESTS ChronoSync',
includes=top,
install_path=None)
# TODO: Re-enable when there integration tests are implemented
# bld.program(
# target="../integrated-tests",
# source=bld.path.ant_glob(['integrated-tests/**/*.cpp']),
# use='ChronoSync tests-main',
# includes=['.'],
# install_path=None,
# )
Vendored
+11 -8
View File
File diff suppressed because one or more lines are too long
+71 -58
View File
@@ -1,86 +1,95 @@
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
VERSION = '0.5.1'
import os
import subprocess
from waflib import Context, Logs
VERSION = '0.5.5'
APPNAME = 'ChronoSync'
GIT_TAG_PREFIX = ''
from waflib import Logs, Utils, Context
import os, subprocess
def options(opt):
opt.load(['compiler_c', 'compiler_cxx', 'gnu_dirs'])
opt.load(['default-compiler-flags', 'boost', 'doxygen', 'sphinx_build',
'coverage', 'sanitizers'],
opt.load(['compiler_cxx', 'gnu_dirs'])
opt.load(['default-compiler-flags',
'coverage', 'sanitizers', 'boost',
'doxygen', 'sphinx_build'],
tooldir=['.waf-tools'])
opt.add_option('--with-tests', action='store_true', default=False,
dest='with_tests', help='''Build unit tests''')
optgrp = opt.add_option_group('ChronoSync Options')
optgrp.add_option('--with-tests', action='store_true', default=False,
help='Build unit tests')
def configure(conf):
conf.load(['compiler_c', 'compiler_cxx', 'gnu_dirs',
'default-compiler-flags', 'boost', 'coverage',
conf.load(['compiler_cxx', 'gnu_dirs',
'default-compiler-flags', 'boost',
'doxygen', 'sphinx_build'])
if 'PKG_CONFIG_PATH' not in os.environ:
os.environ['PKG_CONFIG_PATH'] = Utils.subst_vars('${LIBDIR}/pkgconfig', conf.env)
conf.check_cfg(package='libndn-cxx', args=['--cflags', '--libs'],
uselib_store='NDN_CXX', mandatory=True)
conf.env.WITH_TESTS = conf.options.with_tests
boost_libs = 'system iostreams thread log log_setup'
if conf.options.with_tests:
conf.env['CHRONOSYNC_HAVE_TESTS'] = True
conf.define('CHRONOSYNC_HAVE_TESTS', 1)
boost_libs += ' unit_test_framework'
conf.check_boost(lib=boost_libs, mt=True)
conf.find_program('dot', mandatory=False)
# Prefer pkgconf if it's installed, because it gives more correct results
# on Fedora/CentOS/RHEL/etc. See https://bugzilla.redhat.com/show_bug.cgi?id=1953348
# Store the result in env.PKGCONFIG, which is the variable used inside check_cfg()
conf.find_program(['pkgconf', 'pkg-config'], var='PKGCONFIG')
pkg_config_path = os.environ.get('PKG_CONFIG_PATH', f'{conf.env.LIBDIR}/pkgconfig')
conf.check_cfg(package='libndn-cxx', args=['libndn-cxx >= 0.8.1', '--cflags', '--libs'],
uselib_store='NDN_CXX', pkg_config_path=pkg_config_path)
conf.check_boost(lib='iostreams', mt=True)
if conf.env.BOOST_VERSION_NUMBER < 107100:
conf.fatal('The minimum supported version of Boost is 1.71.0.\n'
'Please upgrade your distribution or manually install a newer version of Boost.\n'
'For more information, see https://redmine.named-data.net/projects/nfd/wiki/Boost')
if conf.env.WITH_TESTS:
conf.check_boost(lib='filesystem unit_test_framework', mt=True, uselib_store='BOOST_TESTS')
conf.check_compiler_flags()
# Loading "late" to prevent tests from being compiled with profiling flags
conf.load('coverage')
conf.load('sanitizers')
# If there happens to be a static library, waf will put the corresponding -L flags
# before dynamic library flags. This can result in compilation failure when the
# system has a different version of the ChronoSync library installed.
conf.env['STLIBPATH'] = ['.'] + conf.env['STLIBPATH']
conf.env.prepend_value('STLIBPATH', ['.'])
conf.write_config_header('config.hpp')
conf.define_cond('WITH_TESTS', conf.env.WITH_TESTS)
# The config header will contain all defines that were added using conf.define()
# or conf.define_cond(). Everything that was added directly to conf.env.DEFINES
# will not appear in the config header, but will instead be passed directly to the
# compiler on the command line.
conf.write_config_header('src/detail/config.hpp', define_prefix='CHRONOSYNC_')
def build(bld):
bld.shlib(
target='ChronoSync',
vnum = VERSION,
cnum = VERSION,
source = bld.path.ant_glob(['src/**/*.cpp', 'src/**/*.proto']),
use = 'BOOST NDN_CXX',
includes = ['src', '.'],
export_includes=['src', '.'])
vnum=VERSION,
cnum=VERSION,
source=bld.path.ant_glob('src/**/*.cpp'),
use='BOOST NDN_CXX',
includes='src/detail',
export_includes='src src/detail')
# Unit tests
if bld.env["CHRONOSYNC_HAVE_TESTS"]:
if bld.env.WITH_TESTS:
bld.recurse('tests')
bld.install_files(
dest = '%s/ChronoSync' % bld.env['INCLUDEDIR'],
files = bld.path.ant_glob(['src/*.hpp', 'common.hpp']),
cwd = bld.path.find_dir("src"),
relative_trick = False,
)
# Install header files
srcdir = bld.path.find_dir('src')
bld.install_files('${INCLUDEDIR}/ChronoSync',
srcdir.ant_glob('**/*.hpp'),
cwd=srcdir,
relative_trick=True)
bld.install_files('${INCLUDEDIR}/ChronoSync/detail', 'src/detail/config.hpp')
bld.install_files(
dest = '%s/ChronoSync' % bld.env['INCLUDEDIR'],
files = bld.path.get_bld().ant_glob(['src/*.hpp', 'common.hpp', 'config.hpp']),
cwd = bld.path.get_bld().find_dir("src"),
relative_trick = False)
bld(features = 'subst',
bld(features='subst',
source='ChronoSync.pc.in',
target='ChronoSync.pc',
install_path = '${LIBDIR}/pkgconfig',
PREFIX = bld.env['PREFIX'],
INCLUDEDIR = "%s/ChronoSync" % bld.env['INCLUDEDIR'],
VERSION = VERSION)
install_path='${LIBDIR}/pkgconfig',
VERSION=VERSION)
def docs(bld):
from waflib import Options
@@ -99,6 +108,7 @@ def doxygen(bld):
target=['docs/doxygen.conf',
'docs/named_data_theme/named_data_footer-with-analytics.html'],
VERSION=VERSION,
HAVE_DOT='YES' if bld.env.DOT else 'NO',
HTML_FOOTER='../build/docs/named_data_theme/named_data_footer-with-analytics.html' \
if os.getenv('GOOGLE_ANALYTICS', None) \
else '../docs/named_data_theme/named_data_footer.html',
@@ -118,7 +128,8 @@ def sphinx(bld):
config='docs/conf.py',
outdir='docs',
source=bld.path.ant_glob('docs/**/*.rst'),
VERSION=VERSION)
version=VERSION_BASE,
release=VERSION)
def version(ctx):
# don't execute more than once
@@ -131,19 +142,19 @@ def version(ctx):
# first, try to get a version string from git
gotVersionFromGit = False
try:
cmd = ['git', 'describe', '--always', '--match', '%s*' % GIT_TAG_PREFIX]
out = subprocess.check_output(cmd, universal_newlines=True).strip()
cmd = ['git', 'describe', '--always', '--match', f'{GIT_TAG_PREFIX}*']
out = subprocess.run(cmd, capture_output=True, check=True, text=True).stdout.strip()
if out:
gotVersionFromGit = True
if out.startswith(GIT_TAG_PREFIX):
Context.g_module.VERSION = out.lstrip(GIT_TAG_PREFIX)
else:
# no tags matched
Context.g_module.VERSION = '%s-commit-%s' % (VERSION_BASE, out)
except subprocess.CalledProcessError:
Context.g_module.VERSION = f'{VERSION_BASE}-commit-{out}'
except (OSError, subprocess.SubprocessError):
pass
versionFile = ctx.path.find_node('VERSION')
versionFile = ctx.path.find_node('VERSION.info')
if not gotVersionFromGit and versionFile is not None:
try:
Context.g_module.VERSION = versionFile.read()
@@ -158,17 +169,19 @@ def version(ctx):
# already up-to-date
return
except EnvironmentError as e:
Logs.warn('%s exists but is not readable (%s)' % (versionFile, e.strerror))
Logs.warn(f'{versionFile} exists but is not readable ({e.strerror})')
else:
versionFile = ctx.path.make_node('VERSION')
versionFile = ctx.path.make_node('VERSION.info')
try:
versionFile.write(Context.g_module.VERSION)
except EnvironmentError as e:
Logs.warn('%s is not writable (%s)' % (versionFile, e.strerror))
Logs.warn(f'{versionFile} is not writable ({e.strerror})')
def dist(ctx):
ctx.algo = 'tar.xz'
version(ctx)
def distcheck(ctx):
ctx.algo = 'tar.xz'
version(ctx)