tcp-udp-tunnel-test: Add test case to test TCP/UDP tunnel.

Refs: #1362

Change-Id: I78f558f61ddd0cf0a363e56081e2e4c735d8156e
diff --git a/test_tcp_udp_tunnel/NDNTrafficClient.conf b/test_tcp_udp_tunnel/NDNTrafficClient.conf
new file mode 100644
index 0000000..320c7c3
--- /dev/null
+++ b/test_tcp_udp_tunnel/NDNTrafficClient.conf
@@ -0,0 +1,6 @@
+##########
+TrafficPercentage=50
+Name=ndn:/tunnel-test/A
+ExpectedContent=AAAAAAAA
+NameAppendBytes=8
+##########
diff --git a/test_tcp_udp_tunnel/NDNTrafficServer.conf b/test_tcp_udp_tunnel/NDNTrafficServer.conf
new file mode 100644
index 0000000..bf0c11c
--- /dev/null
+++ b/test_tcp_udp_tunnel/NDNTrafficServer.conf
@@ -0,0 +1,4 @@
+##########
+Name=ndn:/tunnel-test/A
+Content=AAAAAAAA
+##########
diff --git a/test_tcp_udp_tunnel/README.md b/test_tcp_udp_tunnel/README.md
new file mode 100644
index 0000000..fdc9990
--- /dev/null
+++ b/test_tcp_udp_tunnel/README.md
@@ -0,0 +1,10 @@
+Test correctness of unicast faces.
+
+Host A and D are NDN nodes.  
+Host R is an IP router, and is not a NDN forwarder. This is required in the topology to avoid host A and D communicate over multicast.
+
+1. Start NFD on A and D.
+2. On host A, invoke `nfdc` to initiate a tunnel to D using the given FaceUri.
+3. On host A, invoke `nfdc` to add a nexthop record to the tunnel, so that Interests with prefix "ndn:/tunnel-test" go to D.
+4. Run traffic generator producer on host D, and run traffic generator consumer on host A.
+5. Collect results. The test is considered passed if no interest loss is detected.
diff --git a/test_tcp_udp_tunnel/tcp-udp-tunnel-test.sh b/test_tcp_udp_tunnel/tcp-udp-tunnel-test.sh
new file mode 100755
index 0000000..c9e7710
--- /dev/null
+++ b/test_tcp_udp_tunnel/tcp-udp-tunnel-test.sh
@@ -0,0 +1,70 @@
+#!/usr/bin/env bash
+usage=$'Usage: tcp-udp-tunnel-test.sh [tcp|udp][4|6]'
+if [ $# != 1 ]
+then
+    echo "$usage"
+    exit
+fi
+source ../multi-host.conf
+if [[ ($1 = "tcp4") || ($1 = "udp4") ]]
+then
+    ipaddr="$IP4_D1"
+else
+    ipaddr="[$IP6_D1]"
+fi
+echo "host D IP address $ipaddr"
+
+mkdir -p logs
+
+clean_up() {
+    r=$(ssh $CTRL_D "sudo killall ndn-traffic-server;\
+        sleep 1;\
+        sudo killall nfd" 2>&1)
+    r=$(sudo killall nfd 2>&1)
+}
+
+# start nfd on host A
+sudo nfd > logs/nfd.log 2>&1 &
+
+# start nfd and ndn-traffic-server on host D
+echo "starting nfd and ndn-traffic-server on host D..."
+workdir=$(pwd)
+ssh $CTRL_D "mkdir -p $workdir/logs;\
+    sudo nfd &> $workdir/logs/nfd.log &\
+    sleep 3;\
+    ndn-traffic-server $workdir/NDNTrafficServer.conf > $workdir/logs/server.log 2>&1 &"
+sleep 5
+
+# open a tunnel from host A to host D and set nexthop of ndn:/tunnel-test to D
+echo "preparing tunnel..."
+faceid=$(nfdc create $1://$ipaddr | grep -Po 'FaceId: .*?,' | sed 's/FaceId: //' | sed 's/,//')
+if [[ -z $faceid ]]
+then
+    echo "Fail to create face"
+    clean_up
+    exit 1
+fi
+nfdc add-nexthop ndn:/tunnel-test $faceid
+
+# run ndn-traffic client
+echo "running ndn-traffic client..."
+ndn-traffic -c 100 -i 100 NDNTrafficClient.conf > logs/client.log 2>&1
+
+# stop nfd on hostA
+echo "stopping nfd on host A..."
+sudo killall nfd
+
+# stop ndn-traffic-server and nfd on hostB
+echo "stopping ndn-traffic-server and nfd on host B..."
+clean_up
+
+# examine client log
+echo "analyzing results..."
+output=$(grep "Total Interest Loss" $workdir/logs/client.log | head -1 | cut -d= -f2 | cut -d' ' -f2 | cut -d% -f1)
+if [ $output != '0' ]
+then
+    echo "Expected no Interest Loss. Actual: $output%"
+    echo "For more information, please examine the log at \"$(pwd)/logs\""
+    exit 2
+fi
+echo "Tunnel Test PASSED"
diff --git a/test_tcp_udp_tunnel/test_tcp_udp_tunnel.py b/test_tcp_udp_tunnel/test_tcp_udp_tunnel.py
new file mode 100644
index 0000000..50195e1
--- /dev/null
+++ b/test_tcp_udp_tunnel/test_tcp_udp_tunnel.py
@@ -0,0 +1,56 @@
+#!/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
+
+class test_tcp_udp_tunnel(unittest.TestCase):
+    """Test case for testing TCP/UDP tunnel"""
+
+    errormsg = {
+        1 : "Fail to create face",
+        2 : "Interest loss detected",
+    }
+
+    def setUp(self):
+        print "\nTesting TCP/UDP tunnel"
+        print "**********************"
+        os.chdir("test_tcp_udp_tunnel")
+
+    def tearDown(self):
+        print "**********************"
+        os.chdir("..")
+
+    def test_tcp4(self):
+        print ">>> Testing with TCP4 <<<"
+        ret = subprocess.call(["./tcp-udp-tunnel-test.sh tcp4"], shell=True)
+        print "Test script return value:", ret
+        if (ret != 0):
+            self.fail(self.errormsg[ret])
+
+    def test_udp4(self):
+        print ">>> Testing with UDP4 <<<"
+        ret = subprocess.call(["./tcp-udp-tunnel-test.sh udp4"], shell=True)
+        print "Test script return value:", ret
+        if (ret != 0):
+            self.fail(self.errormsg[ret])
+
+    def test_tcp6(self):
+        print ">>> Testing with TCP6 <<<"
+        ret = subprocess.call(["./tcp-udp-tunnel-test.sh tcp6"], shell=True)
+        print "Test script return value:", ret
+        if (ret != 0):
+            self.fail(self.errormsg[ret])
+
+    def test_udp6(self):
+        print ">>> Testing with UDP6 <<<"
+        ret = subprocess.call(["./tcp-udp-tunnel-test.sh udp6"], shell=True)
+        print "Test script return value:", ret
+        if (ret != 0):
+            self.fail(self.errormsg[ret])