add Docker platform for integration tests
refs #5108
Change-Id: I2855a5d87e4dbca6af02049e0cf423b7c893b2d0
diff --git a/.mailmap b/.mailmap
index a0686d3..c7bb7f3 100644
--- a/.mailmap
+++ b/.mailmap
@@ -1,4 +1,5 @@
-<enewberry@email.arizona.edu> <enewberry@cs.arizona.edu>
+<enewberry@cs.ucla.edu> <enewberry@cs.arizona.edu>
+<enewberry@cs.ucla.edu> <enewberry@email.arizona.edu>
<git@mail1.yoursunny.com> <sjx@a.integ.ndn-routing.emulab.net>
<davidepesa@gmail.com> <davide.pesavento@lip6.fr>
<lybmath2009@gmail.com> <lybmath@ucla.edu>
diff --git a/README.md b/README.md
index 4ce0c0f..7c23fde 100644
--- a/README.md
+++ b/README.md
@@ -1,22 +1,45 @@
-Integration Tests For NFD (nfd-integration-tests)
-=================================================
+# Integration Tests For NFD
-This is a Python based unit test repository which is designed for end-to-end
-integration testing of NDN Forwarding Daemon, NFD.
+This repository contains end-to-end integration tests for the NDN Forwarding Daemon, NFD.
-## Prerequisites ##
+## Prerequisites
-1. Python must be installed (2.7 <= version < 3)
+1. Python 2.7
+2. (if using Docker) Docker
+3. (if using VirtualBox) VirtualBox
+4. (if using VirtualBox) Vagrant
-----------------------------------------------------
-## Setup Instructions: ##
+There are two ways to run the integration tests: automatically (using Docker or VirtualBox+Vagrant) or manually.
+By default, the integration tests will use the latest git master versions of each application.
+This can be overridden using the `repos.conf` file (see `repos.conf.sample` for documentation and examples).
+
+## Running Automatically
+
+The integration tests can be run automatically using either Docker or VirtualBox (via Vagrant).
+This is accomplished by running one of the following commands, depending upon the platform you wish to use:
+
+```bash
+./run.sh docker
+./run.sh vbox
+```
+
+These commands will output test logs to the `logs` folder.
+
+## Running Manually
+
+You may wish the following the following commands when you wish to run the integration tests on physical machines or an existing topology.
+Please note that the integration testing machines must run Ubuntu.
+Since the testing suite uses SSH to communicate with the topology, please edit the `multi-host.conf` file accordingly.
+
+### Install NDN Applications
To install all NDN applications used for the tests, run `./install_apps.py install_all`. To install
one or more particular apps only, find the proper command line argument(s) to use in place of
`install_all` by running `./install_apps.py help`.
-## Test Run Instructions: #
+### Running Tests
-To run all tests, run `./run_tests.py test_all`. To run one or more particular tests, run
-`./run_tests.py help` to find the proper command line argument(s) to use in place of `test_all`.
+To run all tests, run `./run_tests.py test_all`.
+To run one or more particular tests, run `./run_tests.py help` to find the proper command line argument(s) to use in place of `test_all`.
diff --git a/collect-logs.sh b/collect-logs.sh
index 453dd60..0c58b09 100755
--- a/collect-logs.sh
+++ b/collect-logs.sh
@@ -1,4 +1,16 @@
-#!/bin/sh
+#!/bin/bash
+# Collect logs from testing nodes
-cd integration-tests
-tar cf - --ignore-failed-read --exclude='.vagrant*' --exclude='logs*' $(git status -s -uall --porcelain --ignored | awk '$1!="D" && $2!~".pyc$"{print $2}') | tar xf - -C /vagrant/logs/$1
+if [[ ${1} == docker ]]; then
+ integPath=/home/integ/integration-tests
+ outPath=/integ/logs/${2}
+elif [[ ${1} == vbox ]]; then
+ integPath=/home/integ/integration-tests
+ outPath=/vagrant/logs/${2}
+else
+ echo "Invalid test platform specified"
+ exit 1
+fi
+
+cd ${integPath}
+tar -cf - --ignore-failed-read $(git status -s -uall --porcelain --ignored | awk '$1!="D" && $2!~".pyc$"{print $2}' | grep -v -e "^.vagrant" -e "^logs/" -e "^prepare" -e "^temp/") | tar -xf - -C "${outPath}"
diff --git a/docker_helpers/prepare_template.sh b/docker_helpers/prepare_template.sh
new file mode 100755
index 0000000..38e815d
--- /dev/null
+++ b/docker_helpers/prepare_template.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+# Set up common image to build other nodes from
+
+# Install necessary packages
+apt-get update -qq
+apt-get install -qq iproute2 openssh-server psmisc python-minimal sudo
+
+# Set up integ user and SSH
+adduser --disabled-password --gecos "" integ
+echo "integ ALL=(ALL:ALL) NOPASSWD:ALL" >/etc/sudoers.d/integ
+mkdir -p /home/integ/.ssh
+cp /integ/temp/sshkey /home/integ/.ssh/id_rsa
+cp /integ/temp/sshkey.pub /home/integ/.ssh/id_rsa.pub
+cat /home/integ/.ssh/id_rsa.pub >> /home/integ/.ssh/authorized_keys
+chown -R integ:integ /home/integ/.ssh
+chmod -R 700 /home/integ/.ssh
+
+# Copy integ folder and build+install packages
+cp -R /integ /home/integ/integration-tests
+chown -R integ:integ /home/integ/integration-tests
+cd /home/integ/integration-tests && sudo -u integ ./install_apps.py install_all 2>&1 | tee install.log
+chown integ:integ install.log
+rm -rf prepare
+cd install_helpers/tools && sudo -u integ make clean
+
+# Clean up
+sudo apt-get clean
diff --git a/docker_helpers/run_tests.sh b/docker_helpers/run_tests.sh
new file mode 100755
index 0000000..5620da5
--- /dev/null
+++ b/docker_helpers/run_tests.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+# Runs integration tests
+
+cd /home/integ/integration-tests && ./run_tests.py test_all 2>&1 | tee run.log
diff --git a/docker_helpers/setup_A.sh b/docker_helpers/setup_A.sh
new file mode 100755
index 0000000..c5e84dd
--- /dev/null
+++ b/docker_helpers/setup_A.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+# Configuration steps specific to docker instances of node A
+
+cat > /home/integ/.ssh/config <<EOF
+Host 192.168.*.*
+ StrictHostKeyChecking no
+EOF
+chown integ:integ /home/integ/.ssh/config
+
+ip route add 192.168.3.0/24 via 192.168.2.3
+ip -6 route add fd03::/64 via fd02::3
diff --git a/docker_helpers/setup_D.sh b/docker_helpers/setup_D.sh
new file mode 100755
index 0000000..d188bfc
--- /dev/null
+++ b/docker_helpers/setup_D.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+# Configuration steps specific to docker instances of node D
+
+ip route add 192.168.2.0/24 via 192.168.3.2
+ip -6 route add fd02::/64 via fd03::2
diff --git a/docker_helpers/setup_common.sh b/docker_helpers/setup_common.sh
new file mode 100755
index 0000000..6bdb142
--- /dev/null
+++ b/docker_helpers/setup_common.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+# Configuration steps common to all non-router nodes
+
+cp -R /integ ~/integration-tests
+cd ~/integration-tests && ./install_apps.py install_all 2>&1 | tee install.log
+rm -rf prepare
+cd install_helpers/tools && make clean
diff --git a/docker_helpers/setup_router.sh b/docker_helpers/setup_router.sh
new file mode 100755
index 0000000..c629594
--- /dev/null
+++ b/docker_helpers/setup_router.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+# Configuration steps specific to docker instances of router
+
+sysctl net.ipv4.ip_forward=1
+sysctl net.ipv6.conf.all.forwarding=1
diff --git a/install_helpers/install_dependencies.sh b/install_helpers/install_dependencies.sh
index e9b6e7d..ba05dd9 100755
--- a/install_helpers/install_dependencies.sh
+++ b/install_helpers/install_dependencies.sh
@@ -6,4 +6,4 @@
echo "***********************"
sudo apt-get -qq update
-sudo apt-get -qq install build-essential git libboost-all-dev libpcap-dev pkg-config libsqlite3-dev socat bind9 libssl-dev
+sudo apt-get -qq install bind9 build-essential git libboost-all-dev libpcap-dev pkg-config libsqlite3-dev libssl-dev python3-minimal socat
diff --git a/run-vagrant-tests.sh b/run-vagrant-tests.sh
deleted file mode 100755
index 041b492..0000000
--- a/run-vagrant-tests.sh
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/bin/bash
-#
-# Automated integration testing for the Named Data Networking Forwarding Daemon.
-# Part of the Named Data Networking project <http://named-data.net>
-#
-# --
-#
-# Copyright (c) 2014-2018, 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.
-#
-# This file is part of NFD (Named Data Networking Forwarding Daemon).
-# See AUTHORS.md for complete list of NFD authors and contributors.
-#
-# 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.
-#
-# NFD 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/>.
-#
-# Author: Eric Newberry <enewberry@cs.arizona.edu>
-
-mkdir -p logs/A logs/B logs/C logs/D
-mkdir -p temp
-ssh-keygen -t ecdsa -f temp/sshkey -q -N ""
-
-vagrant up template
-vagrant ssh template -c "sudo apt-get clean"
-vagrant package --output nfd-integ.box template
-vagrant box remove nfd-integ
-vagrant box add --name nfd-integ nfd-integ.box
-
-vagrant up router A B C D
-
-vagrant ssh A -c "cd integration-tests && ./run_tests.py test_all 2>&1 | tee run.log"
-vagrant ssh A -c "integration-tests/collect-logs.sh A"
-vagrant ssh B -c "integration-tests/collect-logs.sh B"
-vagrant ssh C -c "integration-tests/collect-logs.sh C"
-vagrant ssh D -c "integration-tests/collect-logs.sh D"
-
-vagrant destroy -f
-
-vagrant box remove nfd-integ
-rm -rf temp prepare
-rm -f nfd-integ.box
diff --git a/run.sh b/run.sh
new file mode 100755
index 0000000..1fb9466
--- /dev/null
+++ b/run.sh
@@ -0,0 +1,154 @@
+#!/bin/bash
+#
+# Automated integration testing for the Named Data Networking Forwarding Daemon.
+# Part of the Named Data Networking project <https://named-data.net>
+#
+# --
+#
+# Copyright (c) 2014-2020, 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.
+#
+# This file is part of NFD (Named Data Networking Forwarding Daemon).
+# See AUTHORS.md for complete list of NFD authors and contributors.
+#
+# 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.
+#
+# NFD 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/>.
+#
+# Author: Eric Newberry <enewberry@cs.ucla.edu>
+
+run_docker() {
+ # Pull docker image if not available
+ echo "Updating docker image..."
+ docker pull ubuntu:18.04
+
+ # Clean up any existing containers, networks, or folders
+ echo "Cleaning any prior runs..."
+ for host in A B C D router template; do
+ docker stop nfd-integ-${host}
+ docker rm nfd-integ-${host}
+ done
+ docker image rm nfd-integ
+ docker network rm nfd-integ-ABC-switch
+ docker network rm nfd-integ-AtoRouter
+ docker network rm nfd-integ-DtoRouter
+
+ # Create and export template
+ echo "Creating template container..."
+ docker run -itd --name nfd-integ-template --mount type=bind,source="$(pwd)",target="/integ" ubuntu:18.04 bash
+ docker exec -it nfd-integ-template /integ/docker_helpers/prepare_template.sh
+ docker commit nfd-integ-template nfd-integ:latest
+ docker stop nfd-integ-template
+ docker rm nfd-integ-template
+
+ # Set up network bridges
+ echo "Setting up networks..."
+ docker network create --ipv6 --subnet 192.168.1.0/24 --subnet fd01::/64 nfd-integ-ABC-switch
+ docker network create --ipv6 --subnet 192.168.2.0/24 --subnet fd02::/64 nfd-integ-AtoRouter
+ docker network create --ipv6 --subnet 192.168.3.0/24 --subnet fd03::/64 nfd-integ-DtoRouter
+
+ # Start containers
+ echo "Starting containers..."
+ for host in A B C D; do
+ docker run -itd --privileged --name nfd-integ-${host} --mount type=bind,source="$(pwd)",target="/integ" nfd-integ bash
+ done
+ docker run -itd --privileged --name nfd-integ-router --mount type=bind,source="$(pwd)",target="/integ" ubuntu:18.04 bash
+
+ # Connect containers to networks
+ echo "Connecting containers to networks..."
+ docker network connect nfd-integ-ABC-switch nfd-integ-A --ip 192.168.1.3 --ip6 fd01::3
+ docker network connect nfd-integ-AtoRouter nfd-integ-A --ip 192.168.2.2 --ip6 fd02::2
+ docker network connect nfd-integ-ABC-switch nfd-integ-B --ip 192.168.1.2 --ip6 fd01::2
+ docker network connect nfd-integ-ABC-switch nfd-integ-C --ip 192.168.1.4 --ip6 fd01::4
+ docker network connect nfd-integ-DtoRouter nfd-integ-D --ip 192.168.3.3 --ip6 fd03::3
+ docker network connect nfd-integ-AtoRouter nfd-integ-router --ip 192.168.2.3 --ip6 fd02::3
+ docker network connect nfd-integ-DtoRouter nfd-integ-router --ip 192.168.3.2 --ip6 fd03::2
+
+ # Start SSH
+ echo "Starting SSH..."
+ for host in A B C D; do
+ docker exec -it nfd-integ-${host} service ssh start
+ done
+
+ # Set up specific nodes
+ echo "Performing container-specific configuration steps..."
+ docker exec -it nfd-integ-A /integ/docker_helpers/setup_A.sh
+ docker exec -it nfd-integ-D /integ/docker_helpers/setup_D.sh
+ docker exec -it nfd-integ-router /integ/docker_helpers/setup_router.sh
+
+ # Run tests
+ echo "Running tests..."
+ docker exec -it nfd-integ-A sudo -i -u integ /integ/docker_helpers/run_tests.sh
+
+ # Collect logs
+ echo "Collecting logs..."
+ for host in A B C D; do
+ docker exec -it nfd-integ-${host} sudo -i -u integ /integ/collect-logs.sh docker ${host}
+ done
+
+ # Stop and remove containers
+ echo "Stopping containers..."
+ for host in A B C D router; do
+ docker stop nfd-integ-${host}
+ docker rm nfd-integ-${host}
+ done
+
+ # Clean up
+ echo "Cleaning up..."
+ docker image rm nfd-integ
+ docker network rm nfd-integ-ABC-switch
+ docker network rm nfd-integ-AtoRouter
+ docker network rm nfd-integ-DtoRouter
+}
+
+run_vbox() {
+ vagrant up template
+ vagrant ssh template -c "sudo apt-get clean"
+ vagrant package --output nfd-integ.box template
+ vagrant box remove nfd-integ
+ vagrant box add --name nfd-integ nfd-integ.box
+
+ vagrant up router A B C D
+
+ vagrant ssh A -c "cd integration-tests && ./run_tests.py test_all 2>&1 | tee run.log"
+ for host in A B C D; do
+ vagrant ssh ${host} -c "integration-tests/collect-logs.sh vbox ${host}"
+ done
+
+ vagrant destroy -f
+
+ vagrant box remove nfd-integ
+ rm -f nfd-integ.box
+}
+
+case ${1} in
+ docker|vbox)
+ ;;
+ *)
+ echo "Usage: ${0} docker|vbox"
+ exit 1
+ ;;
+esac
+
+# Perform steps common to both environments
+rm -rf logs prepare temp
+mkdir -p logs/{A,B,C,D} temp
+ssh-keygen -t ecdsa -f temp/sshkey -q -N ""
+
+# Setup and run using environment-specific steps
+run_${1}
+
+# Clean up
+rm -rf prepare temp