integration-tests: remote prefix registration
Change-Id: Ia0e81879ed353307b325c2ed86b35d7b776b9994
refs: #2201
diff --git a/install_helpers/install_repo.py b/install_helpers/install_repo.py
new file mode 100644
index 0000000..10e2dff
--- /dev/null
+++ b/install_helpers/install_repo.py
@@ -0,0 +1,14 @@
+#!/usr/bin/python2
+import os
+
+# Install ndn-tlv-ping
+def run():
+ print "\nINSTALLING repo-ng"
+ print "***********************"
+ os.system("git clone https://github.com/named-data/repo-ng --depth 1")
+ os.chdir("repo-ng")
+ os.system("./waf distclean")
+ os.system("./waf configure")
+ os.system("./waf -j1")
+ os.system("sudo ./waf install")
+ os.chdir("..")
diff --git a/test_remote_register/A.sh b/test_remote_register/A.sh
new file mode 100755
index 0000000..6de7719
--- /dev/null
+++ b/test_remote_register/A.sh
@@ -0,0 +1,194 @@
+#!/usr/bin/env bash
+defaultIdentity=
+repoDir="test-repo"
+repoConf="$repoDir/test.conf"
+repoDataPrefix='ndn:/Z'
+repoHost='localhost'
+repoPort='9527'
+nfdConf='host.nfd.conf'
+systemNfdConf='/usr/local/etc/ndn/nfd.conf'
+testLog='host.test.log'
+nfdLog='host.nfd.log'
+
+LOG() {
+ echo "[A] $1"
+ echo "[A] $1" >>$testLog
+}
+
+kill_process() {
+ # $1: name of process
+ if [[ $# -lt 1 ]]; then
+ echo "require name of process"
+ exit 1
+ fi
+
+ if pgrep -x $1 > /dev/null; then
+ sudo -b killall -w "$1" >>$testLog 2>&1
+ fi
+}
+
+delete_identity() {
+ # $1: name of identity
+ identity=$1 && identity=${identity#ndn:}
+ if [[ $(ndnsec-list | grep -c "$identity$") -gt 0 ]]; then
+ LOG " deleting identity $1"
+ ndnsec-delete $identity >>$testLog 2>&1
+ else
+ LOG " identity $identity does not exist"
+ fi
+}
+
+clean_up() {
+ LOG "Killing processeses"
+ kill_process "ndn-repo-ng"
+ kill_process "nfd"
+ kill_process "ndnpingserver"
+
+ LOG "Deleting repo data"
+ [[ -d $repoDir ]] && rm -rf $repoDir
+
+ LOG "Deleting identities"
+ delete_identity ndn:/Z
+ delete_identity ndn:/Z/A
+ delete_identity ndn:/Z/A/rib
+ delete_identity ndn:/Z/A/B/C
+ delete_identity ndn:/Z/A/B/C/D/E/rib
+ delete_identity ndn:/Z/F
+
+ if [[ -n "$defaultIdentity" ]]; then
+ if [[ $(ndnsec-list | grep -c "$defaultIdentity$") -gt 0 ]]; then
+ ndnsec-set-default $defaultIdentity
+ fi
+ else
+ r=$(ndnsec-list)
+ if [[ -n "$r" ]]; then
+ r=`echo "$r" | tr "\n" "-"`
+ r=${r%%-*} && r=${r#*/} && r="/$r"
+ ndnsec-set-default $r
+ fi
+ fi
+}
+
+create_identity() {
+ # $1: creating identity
+ # $2: signing identity
+ if [[ $# -gt 1 ]]; then
+ ndnsec-key-gen -n $1 > tmp.req
+ ndnsec-cert-gen -N "tmp" -s $2 -r tmp.req > tmp.cert; rm tmp.req
+ ndnsec-cert-install tmp.cert >>$testLog 2>&1
+ [[ -f tmp.cert ]] && rm tmp.cert
+ elif [[ $# -gt 0 ]]; then
+ ndnsec-key-gen -n $1 | ndnsec-cert-install - >>$testLog 2>&1
+ else
+ echo "require input identity"
+ exit 1
+ fi
+}
+
+publish_default_cert() {
+ # $1: name of identity
+ if [[ $# -lt 1 ]]; then
+ echo "require identity to publish cert"
+ exit 1
+ fi
+
+ if [[ "$1"x = "${1#${repoDataPrefix}}"x ]]; then
+ echo "can not publish $1 under $repoDataPrefix"
+ exit 1
+ fi
+
+ ndnsec-cert-dump -r -H $repoHost -P $repoPort -i $1
+}
+
+start_repo() {
+ LOG "create repo dir config file for repo"
+ [[ -d $repoDir ]] || mkdir -p $repoDir
+
+ echo "" > $repoConf # create repo conf file
+
+ infoedit -f $repoConf -s repo.data.prefix -v $repoDataPrefix
+ infoedit -f $repoConf -s repo.command.prefix -v ""
+ infoedit -f $repoConf -s repo.storage.method -v sqlite
+ infoedit -f $repoConf -s repo.storage.path -v $repoDir
+ infoedit -f $repoConf -s repo.storage.max-packets -v 100
+ infoedit -f $repoConf -s repo.tcp_bulk_insert.host -v $repoHost
+ infoedit -f $repoConf -s repo.tcp_bulk_insert.port -v $repoPort
+ infoedit -f $repoConf -s repo.validator.trust-anchor.type -v any
+
+ kill_process ndn-repo-ng
+ LOG "start repo-ng"
+ nohup ndn-repo-ng -c $repoConf >>$testLog 2>&1 &
+}
+
+start_nfd() {
+ LOG "create nfd conf file with remote_register section specified for test"
+ [[ ! -f $systemNfdConf ]] && LOG "can not find nfd config file" && exit 1
+
+ cp $systemNfdConf $nfdConf
+ infoedit -f $nfdConf -s rib.remote_register.cost -v 15
+ infoedit -f $nfdConf -s rib.remote_register.timeout -v 10000
+ infoedit -f $nfdConf -s rib.remote_register.retry -v 0
+ infoedit -f $nfdConf -s rib.remote_register.refresh_interval -v 15
+
+ kill_process nfd
+ LOG "start NFD"
+ sudo nohup nfd --config $nfdConf >>$nfdLog 2>&1 &
+}
+
+prepare_for_test() {
+ echo "Start test log on end host" >$testLog
+ echo "Start nfd log on end host" >$nfdLog
+
+ start_nfd && sleep 2
+
+ start_repo && sleep 2
+
+ defaultIdentity=$(ndnsec-get-default)
+
+ # create identities and publish their certificates
+ LOG "create identity /Z/A and publish its cert"
+ create_identity ndn:/Z/A
+ publish_default_cert ndn:/Z/A
+
+ LOG "create identity /Z/A/nrd and publish its cert"
+ create_identity ndn:/Z/A/rib ndn:/Z/A
+ publish_default_cert ndn:/Z/A/rib
+
+ LOG "create identity /Z/A/B/C and publish its cert"
+ create_identity ndn:/Z/A/B/C ndn:/Z/A
+ publish_default_cert ndn:/Z/A/B/C
+
+ LOG "create identity /Z/A/B/C/D/E/nrd and publish its cert"
+ create_identity ndn:/Z/A/B/C/D/E/rib ndn:/Z/A/B/C
+ publish_default_cert ndn:/Z/A/B/C/D/E/rib
+
+ LOG "create identity /Z/F and publish its cert"
+ create_identity ndn:/Z/F ndn:/Z
+ publish_default_cert ndn:/Z/F
+}
+
+generate_anchor() {
+ certFile='remote-register.hub.anchor.cert'
+ ndnsec-export -o $certFile $1 >>$testLog 2>&1
+ cert=$(cat $certFile) && rm $certFile
+ echo $cert
+}
+
+while getopts "a:cp" arg
+ do
+ case $arg in
+ a)
+ generate_anchor $OPTARG
+ ;;
+ c)
+ clean_up
+ ;;
+ p)
+ prepare_for_test
+ ;;
+ ?)
+ echo "unknown argument"
+ exit 1
+ ;;
+ esac
+done
diff --git a/test_remote_register/B.sh b/test_remote_register/B.sh
new file mode 100755
index 0000000..d8b6cf5
--- /dev/null
+++ b/test_remote_register/B.sh
@@ -0,0 +1,149 @@
+#!/usr/bin/env bash
+
+defaultIdentity=
+hubIdentity='/remote-register-test/hub'
+nfdConf='hub.nfd.conf'
+systemNfdConf='/usr/local/etc/ndn/nfd.conf'
+testLog='hub.test.log'
+nfdLog='hub.nfd.log'
+
+LOG() {
+ echo "[B] $1"
+ echo "[B] $1" >>$testLog
+}
+
+kill_process() {
+ # $1: name of process
+ if [[ $# -lt 1 ]]; then
+ echo "require process name"
+ exit 1
+ fi
+
+ if pgrep -x $1 > /dev/null; then
+ sudo -b killall -w "$1" >>$testLog 2>&1
+ fi
+}
+
+delete_identity() {
+ # $1: name of identity
+ if [[ $(ndnsec-list | grep -c "$1$") -gt 0 ]]; then
+ LOG " deleting identity $1!"
+ ndnsec-delete $1 >>$testLog 2>&1
+ else
+ LOG " identity $1 does not exist"
+ fi
+}
+
+clean_up() {
+ LOG "Killing NFD process!"
+ kill_process nfd
+ kill_process ndn-autoconfig-server
+
+ LOG "Deleting the hub identity"
+ delete_identity "$hubIdentity"
+
+ LOG "Reset the default identity"
+ if [[ -n "$defaultIdentity" ]]; then
+ if [[ $(ndnsec-list | grep -c "$defaultIdentity$") -gt 0 ]]; then
+ ndnsec-set-default $defaultIdentity
+ fi
+ else
+ r=$(ndnsec-list)
+ if [[ -n "$r" ]]; then
+ r=`echo "$r" | tr "\n" "-"`
+ r=${r%%-*} && r=${r#*/} && r="/$r"
+ ndnsec-set-default $r
+ fi
+ fi
+}
+
+prepare_for_test() {
+ echo "Start test log on remote hub" >$testLog
+ echo "Start nfd log on remote hub" >$nfdLog
+
+ LOG "Create hub identity as the default identity"
+ defaultIdentity=$(ndnsec-get-default)
+ ndnsec-key-gen $hubIdentity | ndnsec-cert-install - >>$testLog 2>&1
+
+ LOG "create nfd conf file with localhop_security section specified for test"
+ [[ ! -f $systemNfdConf ]] && LOG "can not find nfd config file" && exit 1
+
+ # copy the config file to the working directory
+ cp $systemNfdConf $nfdConf
+
+ # insert a rule section to validate Interest
+ cat <<EOF | infoedit -f $nfdConf -a rib.localhop_security.rule
+id "NRD Prefix Registration Command Rule"
+for interest
+filter
+{
+ type name
+ regex ^[<localhop><localhost>]<nfd><rib>[<register><unregister>]<>$
+}
+checker
+{
+ type customized
+ sig-type rsa-sha256
+ key-locator
+ {
+ type name
+ regex ^[^<KEY>]*<KEY><>*[<ksk-.*>]<ID-CERT>$
+ }
+}
+EOF
+
+ #insert a rule section to validate Data
+ cat <<EOF | infoedit -f $nfdConf -a rib.localhop_security.rule
+id "NDN Testbed Hierarchy Rule"
+for data
+filter
+{
+ type name
+ regex ^[^<KEY>]*<KEY><>*[<ksk-.*>]<ID-CERT><>*$
+}
+checker
+{
+ type customized
+ sig-type rsa-sha256
+ key-locator
+ {
+ type name
+ regex ^[^<KEY>]*<KEY><>*[<ksk-.*>]<ID-CERT>$
+ }
+}
+EOF
+
+ #insert a trust-anchor section
+ cat <<EOF | infoedit -f $nfdConf -a rib.localhop_security.trust-anchor
+type file
+file-name anchor.cert
+EOF
+
+ #delete remote_register section
+ infoedit -f $nfdConf -d rib.remote_register
+
+ kill_process nfd
+ LOG "start NFD"
+ sudo -b nohup nfd --config $nfdConf >>$nfdLog 2>&1 &
+ sleep 2
+
+ LOG "set autoreg prefix to ndn:/"
+ nfdc set-strategy ndn:/ ndn:/localhost/nfd/strategy/broadcast >>$testLog 2>&1
+ nfd-autoreg --prefix=/Z >> $testLog 2>&1 &
+}
+
+while getopts "a:cp" arg
+ do
+ case $arg in
+ c)
+ clean_up
+ ;;
+ p)
+ prepare_for_test
+ ;;
+ ?)
+ echo "unknown argument"
+ exit 1
+ ;;
+ esac
+done
diff --git a/test_remote_register/README.md b/test_remote_register/README.md
new file mode 100644
index 0000000..dca5242
--- /dev/null
+++ b/test_remote_register/README.md
@@ -0,0 +1,84 @@
+Test Case - remote prefix registration test scenario
+=====================
+
+## Topology
+A--B
+
+A is a NDN host while B is the remote hub / gateway router.
+IPv4 udp tunnel is used.
+
+Script is invoked on host A. It can control B via ssh
+
+## Description
+The script test remote prefix registration procedure.
+In case of a failure, the detailed log can be found under:
+test_remote_register/logs/remote_register.log
+
+## Steps
+1. generate certificates on A for these identities, in RIB daemon's KeyChain:
+ ndn:/Z/A self-signed
+ ndn:/Z/A/nrd signed by ndn:/Z/A
+ ndn:/Z/A/B/C signed by ndn:/Z/A
+ ndn:/Z/A/B/C/D/E/nrd signed by ndn:/Z/A/B/C
+ ndn:/Z/F self-signed
+
+2. configure NFD on A:
+ enable remote prefix registration
+ set remote registration refreshing time to 15 seconds
+
+3. configure NFD on B:
+ set UDP face timeout to 35 seconds
+ enable acceptance of prefix registration using ndn:/localhop/nfd/rib command prefix
+ make ndn:/Z/A a trust anchor for prefix registration using ndn:/localhop/nfd/rib command prefix
+ set broadcast strategy for ndn:/
+
+4. start NFD (including RIB Daemon) on A,B
+
+5. start repo-ng on A to listen on ndn:/ prefix, and put all certificates generated in step 1 into this repo via TCP bulk insert protocol
+
+6. start nfd-autoreg --prefix=/Z on B
+
+7. execute nfdc on A to create a face toward B over UDP
+
+8. start ndnpingserver for ndn:/Z/A/G on A, defer 5 seconds
+
+9. inspect RIB on B, fail the test case if Route for ndn:/Z/A toward A exists
+
+10. execute nfdc on A to register a Route for ndn:/localhop/nfd on the face created in step 7
+
+11. defer 5 seconds
+
+12. inspect RIB on B, fail the test case if Route for ndn:/Z/A toward A does not exist
+
+13. start ndnpingserver for ndn:/Z/A/H on A, defer 5 seconds
+
+14. inspect RIB on B, fail the test case if Route for ndn:/Z/A toward A does not exist
+
+15. stop ndnpingserver from step 8, defer 5 seconds
+
+16. inspect RIB on B, fail the test case if Route for ndn:/Z/A toward A does not exist
+
+17. stop ndnpingserver from step 13, defer 5 seconds
+
+18. inspect RIB on B, fail the test case if Route for ndn:/Z/A toward A exists
+
+19. start ndnpingserver for ndn:/Z/A/B/C/D on A, defer 5 seconds
+
+20. inspect RIB on B, fail the test case if Route for ndn:/Z/A toward A exists, fail the test case if Route for ndn:/Z/A/B/C toward A does not exist
+
+21. stop ndnpingserver from step 19
+
+22. start ndnpingserver for ndn:/Z/A/B/C/D/E on A, defer 5 seconds
+
+23. inspect RIB on B, fail the test case if Route for ndn:/Z/A toward A exists, fail the test case if Route for ndn:/Z/A/B/C toward A exists, fail the test case if Route for ndn:/Z/A/B/C/D/E toward A does not exist
+
+24. defer 80 seconds
+
+25. inspect RIB on B, fail the test case if Route for ndn:/Z/A/B/C/D/E toward A does not exist
+
+26. start ndnpingserver for ndn:/Z/F/I on A, defer 5 seconds
+
+27. inspect RIB on B, fail the test case if Route for ndn:/Z/F toward A exists
+
+## Return value
+PASS of all tests finished successfully.
diff --git a/test_remote_register/remote-register-test.sh b/test_remote_register/remote-register-test.sh
new file mode 100755
index 0000000..543a5f5
--- /dev/null
+++ b/test_remote_register/remote-register-test.sh
@@ -0,0 +1,122 @@
+#!/usr/bin/env bash
+source ../multi-host.conf
+testCase=$1
+workDir=$(pwd)
+logDir=$workDir/logs
+hostIP=$IP4_A1
+hubIP=$IP4_B1
+testLog=$logDir/remote-register.log
+hostSh=A.sh
+hubSh=B.sh
+
+echo "TEST REMOTE REGISTER START" >$testLog
+
+LOG () {
+ echo $1; echo $1 >>$testLog
+}
+
+run_hub_cmd () {
+ ssh $hubIP "$1" 2>&1
+}
+
+run_scp_to_hub () {
+ scp $1 $hubIP:$workDir/$1 2>&1
+}
+
+set_hub_trust_anchor () {
+ LOG "set the trust anchor to $1 on the hub."
+ anchor=$(sh $hostSh -a $1)
+ echo $anchor > anchor.cert
+ run_scp_to_hub anchor.cert && rm anchor.cert
+}
+
+run_host_ping_server() {
+ ndnpingserver $1 >>$testLog 2>&1 &
+}
+
+end_test() {
+ scp $hubIP:$workDir/hub.nfd.log hub.nfd.log 2>&1
+ scp $hubIP:$workDir/hub.test.log hub.test.log 2>&1
+ cat host.nfd.log hub.nfd.log > nfd.log
+ cat host.test.log hub.test.log > test.log
+ cat nfd.log test.log >> $testLog
+
+ bash $hostSh -c && run_hub_cmd "cd $workDir && bash $hubSh -c"
+ run_hub_cmd "[[ -d $workDir ]] && sudo rm -rf $workDir"
+ rm *.log
+
+ [[ $# -gt 0 ]] && LOG "$1" && exit 1 || exit 0
+}
+
+inspect_hub_rib_exist() {
+ record=$(run_hub_cmd "nfd-status -r" | grep "$1 route")
+ if [[ -z "$record" ]]; then
+ end_test "Fail test $2"
+ fi
+}
+
+inspect_hub_rib_none() {
+ record=$(run_hub_cmd "nfd-status -r" | grep "$1 route")
+ if [[ ! -z "$record" ]]; then
+ end_test "Fail test $2. the matched record: $record"
+ fi
+}
+
+run_test() {
+ faceUri=udp4://$hubIP:6363
+ nfdc create $faceUri >> $testLog
+
+ defer_time=5 && test_case=0
+
+ test_case=`expr $test_case + 1` && LOG "run test case: $test_case" #1
+ run_host_ping_server ndn:/Z/A/G && p1=$! && sleep $defer_time
+ inspect_hub_rib_none /Z/A "$test_case: route of /Z/A exists."
+
+ test_case=`expr $test_case + 1` && LOG "run test case: $test_case" #2
+ nfdc register ndn:/localhop/nfd $faceUri >> $testLog
+ # the route of /Z/A is expected to exist. But due to BUG 2413, it will not
+ inspect_hub_rib_none /Z/A "$test_case: route of /Z/A does not exist."
+
+ test_case=`expr $test_case + 1` && LOG "run test case: $test_case" #3
+ run_host_ping_server ndn:/Z/A/H && p2=$! && sleep $defer_time
+ inspect_hub_rib_exist /Z/A "$test_case: route of /Z/A does not exist."
+
+ test_case=`expr $test_case + 1` && LOG "run test case: $test_case" #4
+ sudo kill $p1 && sleep $defer_time
+ inspect_hub_rib_exist /Z/A "$test_case: route of /Z/A was unregistered."
+
+ test_case=`expr $test_case + 1` && LOG "run test case: $test_case" #5
+ sudo kill $p2 && sleep $defer_time
+ inspect_hub_rib_none /Z/A "$test_case: route of /Z/A still exists."
+
+ test_case=`expr $test_case + 1` && LOG "run test case: $test_case" #6
+ run_host_ping_server ndn:/Z/A/B/C/D && p3=$! && sleep $defer_time
+ inspect_hub_rib_none /Z/A "$test_case: route of /Z/A exists."
+ inspect_hub_rib_exist /Z/A/B/C "$test_case: route of /Z/A/B/C does not exist."
+
+ test_case=`expr $test_case + 1` && LOG "run test case: $test_case" #7
+ sudo kill $p3 && run_host_ping_server ndn:/Z/A/B/C/D/E && sleep $defer_time
+ inspect_hub_rib_none /Z/A "$test_case: route of /Z/A exists."
+ inspect_hub_rib_none /Z/A/B/C "$test_case: route of /Z/A/B/C exists."
+ inspect_hub_rib_exist /Z/A/B/C/D/E "$test_case: route of /Z/A/B/C/D/E does not exist."
+
+ test_case=`expr $test_case + 1` && LOG "run test case: $test_case" #8
+ sleep 80
+ inspect_hub_rib_exist /Z/A/B/C/D/E "$test_case: route of /Z/A/B/C/D/E does not exist."
+
+ test_case=`expr $test_case + 1` && LOG "run test case: $test_case" #9
+ run_host_ping_server ndn:/Z/F/I && sleep $defer_time
+ inspect_hub_rib_none /Z/F "$test_case: route of /Z/F exist."
+}
+
+LOG "set environment in the host."
+bash $hostSh -c -p
+
+LOG "set environment in the hub."
+run_hub_cmd "[[ -d $workDir ]] || mkdir -p $workDir"
+run_scp_to_hub $hubSh
+set_hub_trust_anchor ndn:/Z/A
+run_hub_cmd "cd $workDir && bash $hubSh -c -p"
+
+LOG "run test"
+run_test && end_test
diff --git a/test_remote_register/test_remote_register.py b/test_remote_register/test_remote_register.py
new file mode 100644
index 0000000..44f5abd
--- /dev/null
+++ b/test_remote_register/test_remote_register.py
@@ -0,0 +1,28 @@
+#!/usr/bin/python2
+
+import os
+import unittest
+import subprocess
+
+class test_remote_register(unittest.TestCase):
+ """Test case for testing NDN Remote Prefix Registration"""
+
+ def setUp(self):
+ print "\nTesting NDN remote prefix registration"
+ print "*****************************"
+ os.chdir("test_remote_register")
+ os.system("mkdir -p logs")
+
+ def tearDown(self):
+ print "********************************"
+ os.chdir("..")
+
+ def test_remote_register(self):
+ print ">>> test remote prefix registration <<<"
+
+ ret = subprocess.call(['./remote-register-test.sh'], shell=True)
+
+ if (ret != 0):
+ self.fail(" >> TEST REMOTE REGISTER PROCEDURE FAILED")
+ else:
+ print ">> TEST REMOTE REGISTER PROCEDURE PASSED SUCCESSFULLY"