localhost-scope-control-test: /localhost scope control scenario
refs #1391
Change-Id: I5c437dd234f929bcb41d78a8b68f93cad171af42
diff --git a/test_localhost_scope/NDNTrafficServer.conf b/test_localhost_scope/NDNTrafficServer.conf
new file mode 100644
index 0000000..a8c70b2
--- /dev/null
+++ b/test_localhost_scope/NDNTrafficServer.conf
@@ -0,0 +1,4 @@
+##########
+Name=ndn:/localhost/test-in
+Content=AAAAAAAA
+##########
diff --git a/test_localhost_scope/README.md b/test_localhost_scope/README.md
new file mode 100644
index 0000000..deda7a6
--- /dev/null
+++ b/test_localhost_scope/README.md
@@ -0,0 +1,32 @@
+# /localhost scope scenario
+
+Topology: A-B. All are NDN nodes.
+
+## Incoming scope control
+
+1. On host B, start NFD.
+2. On host B, start ndn-traffic-server to serve `ndn:/localhost/test-in`.
+3. On host A, start [socat](http://linux.die.net/man/1/socat) to create a relay from a listening UNIX socket to TCP hostB:6363.
+ Write the path of this UNIX socket to `$HOME/.ndn/client.conf`.
+4. On host A, invoke ndn-tlv-peek to request `ndn:/localhost/test-in/A`.
+ Fail if Interest is answered.
+5. On host B, stop ndn-traffic-server.
+ Fail if total served Interest does not equal 0.
+6. On host A, kill socat and restore `$HOME/.ndn/client.conf`.
+
+## Outgoing scope control
+
+1. On host A, start [netcat](http://linux.die.net/man/1/nc) to listen on TCP port 6363.
+ Redirect netcat output into a file.
+2. On host B, invoke nfdc to create face tcp://hostA:6363.
+ Fail if nfdc fails.
+3. On host B, invoke nfdc to add nexthop for `ndn:/` toward face created in step 8.
+ Fail if nfdc fails.
+4. On host B, invoke nfdc to add nexthop for `ndn:/localhost/test-out` toward face created in step 8.
+ Do not fail if nfdc fails (forwarder MAY reject prefix registration that violates scope control).
+5. On host B, invoke ndn-tlv-peek to request `ndn:/localhost/test-out/B/c39b6fed4ce4464ea136062f80002c7c`.
+6. On host B, invoke ndn-tlv-peek to request `ndn:/localhost/C/c39b6fed4ce4464ea136062f80002c7c`.
+7. On host B, invoke ndn-tlv-peek to request `ndn:/ref-out/D/3b5fe3f184ff48adb3523180dee50555`.
+8. On host A, stop netcat.
+ Search netcat output for string "c39b6fed4ce4464ea136062f80002c7c". Fail if this string exists.
+ Search netcat output for string "3b5fe3f184ff48adb3523180dee50555". Fail if this string does not exist.
diff --git a/test_localhost_scope/__init__.py b/test_localhost_scope/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test_localhost_scope/__init__.py
diff --git a/test_localhost_scope/in-master.sh b/test_localhost_scope/in-master.sh
new file mode 100755
index 0000000..faca555
--- /dev/null
+++ b/test_localhost_scope/in-master.sh
@@ -0,0 +1,51 @@
+#!/usr/bin/env bash
+source ../multi-host.conf
+mkdir -p logs
+workdir=$(pwd)
+
+clean_up() {
+ r=$(mv $HOME/.ndn/client.conf.bk $HOME/.ndn/client.conf 2>&1)
+ r=$(killall socat 2>&1)
+ r=$(ssh $CTRL_B "killall ndn-traffic-server;\
+ sudo killall nfd" 2>&1)
+}
+
+# start nfd and ndn-traffic-server on hostB
+ssh $CTRL_B "mkdir -p $workdir/logs;\
+ sudo nfd &> $workdir/logs/nfd.log &\
+ sleep 2;\
+ ndn-traffic-server $workdir/NDNTrafficServer.conf &> $workdir/logs/server.log &"
+sleep 2
+
+# set up socat on A
+cp $HOME/.ndn/client.conf $HOME/.ndn/client.conf.bk
+socat -v UNIX-LISTEN:/tmp/localhost-test-B.sock,fork TCP:$IP4_B1:6363 &> logs/socat.log &
+sed -i 's/^unix_socket=.*$/unix_socket=\/tmp\/localhost-test-B.sock/g' $HOME/.ndn/client.conf
+sleep 1
+
+# send interest
+response=$(ndn-tlv-peek -p ndn:/localhost/test-in/A 2>&1)
+if [[ ! -z $response ]]
+then
+ echo "FAIL: Expected no data come back for ndn:/localhost/test-in/A, Actual: '$response'"
+ clean_up
+ exit 2
+fi
+
+# copy back the server log
+ssh $CTRL_B "killall ndn-traffic-server"
+scp $CTRL_B:$workdir/logs/server.log $workdir/logs/
+
+# analyze server log
+output=$(grep "Total Interests Received" $workdir/logs/server.log | head -1 | cut -d= -f2 | cut -d' ' -f2)
+if [[ $output != '0' ]]
+then
+ echo "Expected no Interests received on host B. Actual: $output"
+ echo "For more information, please examine the log at \"$(pwd)/logs\""
+ clean_up
+ exit 3
+fi
+
+clean_up
+
+echo "localhost incoming test PASSED"
diff --git a/test_localhost_scope/out-B.sh b/test_localhost_scope/out-B.sh
new file mode 100755
index 0000000..df0bf29
--- /dev/null
+++ b/test_localhost_scope/out-B.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+FACEURI=$1
+
+if ! CREATE=$(nfdc create $FACEURI)
+then
+ return 1
+fi
+sleep 1
+
+FACEID=$(echo $CREATE | grep -Po 'FaceId: .*?,' | sed 's/FaceId: //' | sed 's/,//')
+
+if ! output=$(nfdc add-nexthop ndn:/ $FACEID)
+then
+ return 2
+fi
+
+output=$(nfdc add-nexthop ndn:/localhost/test-out $FACEID 2>&1)
+return 0
diff --git a/test_localhost_scope/out-master.sh b/test_localhost_scope/out-master.sh
new file mode 100755
index 0000000..5c3c149
--- /dev/null
+++ b/test_localhost_scope/out-master.sh
@@ -0,0 +1,54 @@
+#!/usr/bin/env bash
+source ../multi-host.conf
+mkdir -p logs
+workdir=$(pwd)
+
+clean_up() {
+ r=$(killall nc 2>&1)
+ r=$(ssh $CTRL_B "sudo killall nfd" 2>&1)
+}
+
+# start NFD on B
+ssh $CTRL_B "sudo nfd > $workdir/logs/nfd.log 2>&1 &"
+
+# start netcat on A
+nc -vul 6363 > $workdir/logs/netcat.log 2>&1 &
+sleep 1
+
+# add nexthop of ndn:/ and ndn:/localhost/test-out to hostA
+if ! status=$(ssh $CTRL_B "source $workdir/out-B.sh udp4://$IP4_A1" 2>&1)
+then
+ echo "Error message from host B:"
+ echo "$status"
+ clean_up
+ exit 4
+fi
+
+# On B, use ndn-tlv-peek to request names that starts with ndn:/localhost
+r=$(ssh $CTRL_B "ndn-tlv-peek -p ndn:/localhost/test-out/B/c39b6fed4ce4464ea136062f80002c7c;\
+ ndn-tlv-peek -p ndn:/localhost/C/c39b6fed4ce4464ea136062f80002c7c;\
+ ndn-tlv-peek -p ndn:/ref-out/D/3b5fe3f184ff48adb3523180dee50555")
+sleep 2
+
+# stop netcat and examine netcat.log
+ssh $CTRL_B "sudo killall nfd"
+output=$(killall nc)
+sleep 1
+output=$(grep "c39b6fed4ce4464ea136062f80002c7c" $workdir/logs/netcat.log)
+if [[ -n $output ]]
+then
+ echo "FAIL: /localhost Interest reaches remote host."
+ clean_up
+ exit 7
+fi
+output=$(grep "3b5fe3f184ff48adb3523180dee50555" $workdir/logs/netcat.log)
+if [[ -z $output ]]
+then
+ echo "FAIL: non-/localhost Interest does not reach remote host."
+ clean_up
+ exit 9
+fi
+
+# clean up
+clean_up
+echo "localhost outgoing test PASSED"
diff --git a/test_localhost_scope/test_localhost_scope.py b/test_localhost_scope/test_localhost_scope.py
new file mode 100644
index 0000000..cbc014e
--- /dev/null
+++ b/test_localhost_scope/test_localhost_scope.py
@@ -0,0 +1,43 @@
+#!/usr/bin/python2
+# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+#
+# Copyright (C) 2014 University of Arizona
+# Author: Yi Huang <ltr120@email.arizona.edu>
+# See COPYING for copyright and distribution information.
+#
+
+import os
+import unittest
+import subprocess
+import ConfigParser
+
+class test_localhost_scope(unittest.TestCase):
+ """Test case for testing /localhost scope control"""
+
+ def setUp(self):
+ print "\nTesting /localhost scope control"
+ print "********************************"
+ os.chdir("test_localhost_scope")
+
+ def tearDown(self):
+ print "********************************"
+ os.chdir("..")
+
+ def test_localhost_scope_in(self):
+ ret = subprocess.call(["./in-master.sh"], shell=True)
+ errormsg = {
+ 2 : "Data packet came back to A (expected no data come back)",
+ 3 : "Interest from A was received on B",
+ }
+ if (ret != 0):
+ self.fail(errormsg[ret])
+
+ def test_localhost_scope_out(self):
+ ret = subprocess.call(["./out-master.sh"], shell=True)
+ errormsg = {
+ 4 : "Fail to add nexthop to A on B",
+ 7 : "/localhost Interest reaches remote host.",
+ 9 : "non-/localhost Interest does not reach remote host.",
+ }
+ if (ret != 0):
+ self.fail(errormsg[ret])