2016-11-29 11:34:37 +00:00
|
|
|
#!/bin/bash -eux
|
|
|
|
# (c) 2016, John Barker <jobarker@redhat.com>
|
|
|
|
#
|
|
|
|
# This file is part of Ansible
|
|
|
|
#
|
|
|
|
# Ansible 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.
|
|
|
|
#
|
|
|
|
# Ansible 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 Ansible. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
########################################################
|
|
|
|
|
|
|
|
# FIXME Describe purpose, process, directory structure, and state/variables
|
|
|
|
|
|
|
|
|
|
|
|
readonly PROG="${0##*/}"
|
|
|
|
readonly LOCKFILE_DIR=/tmp
|
|
|
|
readonly LOCK_FD=200
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
##
|
|
|
|
# Validate command line arguments
|
|
|
|
|
|
|
|
if [ "$#" -ne 2 ]; then
|
|
|
|
echo "Invalid arguments provided" >&2
|
|
|
|
echo >&2
|
|
|
|
echo "USAGE: $0 platform branch" >&2
|
|
|
|
echo >&2
|
|
|
|
echo " $0 ios devel" >&2
|
|
|
|
echo " $0 junos stable-2.2" >&2
|
|
|
|
exit 2
|
|
|
|
fi
|
|
|
|
|
|
|
|
platform=$1
|
|
|
|
branches=$2
|
|
|
|
|
|
|
|
|
|
|
|
inventory="inventory.network" # FIXME This file will updating to reference the DUT VMs once they exist
|
|
|
|
|
|
|
|
# FIXME Describe directory structure here
|
|
|
|
basedir="/tmp/run-network-test"
|
|
|
|
log_root="/var/www/html/network-tests/logs"
|
2016-11-29 18:44:31 +00:00
|
|
|
#DEBUG_LOGFILE="${basedir}/${PROG}-$(date '+%s').log"
|
2016-11-29 11:34:37 +00:00
|
|
|
|
|
|
|
main() {
|
|
|
|
validate_tools
|
|
|
|
setup_environment
|
|
|
|
|
|
|
|
echo "Platform: '${platform}'"
|
|
|
|
echo "Branches: '${branches}'"
|
|
|
|
|
|
|
|
# Ensure we don't run more than one instance of the tests per platform.
|
|
|
|
# As we only have one test machine per platform we can't run more than one test
|
|
|
|
# at once
|
|
|
|
|
|
|
|
# Use the flock method from http://www.kfirlavi.com/blog/2012/11/06/elegant-locking-of-bash-program/
|
|
|
|
lock "${PROG}-${platform}" \
|
|
|
|
|| eexit "Only one instance of ${PROG} can run on ${platform} at one time."
|
|
|
|
run_tests
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
setup_environment() {
|
|
|
|
if [ -d "${basedir}" ]; then
|
|
|
|
mkdir -p "${basedir}"
|
|
|
|
fi
|
|
|
|
|
|
|
|
# FIXME Create HTML template if it doesn't already exist
|
|
|
|
|
|
|
|
if [ ! -e "${log_root}/results.html" ]; then
|
|
|
|
# First run so write out the top of the HTML results page
|
|
|
|
echo "One time setup: Creating '${log_root}/results.html'"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cat << 'EOF' > "${log_root}/results.html"
|
|
|
|
<html>
|
|
|
|
<title>Ansible Network Test Results</title>
|
|
|
|
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/dt/jq-2.2.3/dt-1.10.12/datatables.min.css"/>
|
|
|
|
<script type="text/javascript" src="https://cdn.datatables.net/v/dt/jq-2.2.3/dt-1.10.12/datatables.min.js"></script>
|
|
|
|
<script>
|
|
|
|
// https://datatables.net/blog/2014-12-18 May need this
|
|
|
|
$(document).ready(function(){
|
|
|
|
$('#results').DataTable({
|
|
|
|
// Newest result on top
|
|
|
|
"order": [[ 0, "desc" ]],
|
|
|
|
// show all results
|
|
|
|
paging: false
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
</script>
|
|
|
|
<body>
|
|
|
|
<table id="results" class="datatable table table-striped table-bordered display" cellspacing="0" width="100%">
|
|
|
|
<thead>
|
|
|
|
<tr>
|
|
|
|
<th>Date</th>
|
|
|
|
<th>Branch</th>
|
|
|
|
<th>sha1</th>
|
|
|
|
<th>Platform</th>
|
|
|
|
<th>Result</th>
|
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
|
|
|
EOF
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# We key of platform as the Test VMs are the limiting factor, not the branches
|
|
|
|
# run-network-test/platform/devel
|
|
|
|
|
|
|
|
run_tests() {
|
|
|
|
|
|
|
|
for branch in ${branches//,/ }
|
|
|
|
do
|
|
|
|
echo "Inspecting: ${branch}"
|
|
|
|
echo "Updating git repo..."
|
|
|
|
|
|
|
|
branch_dir="${basedir}/${platform}/${branch}"
|
|
|
|
ansible_dir="${branch_dir}/ansible"
|
|
|
|
if [ -d "${ansible_dir}" ]; then
|
|
|
|
git -C "${ansible_dir}" pull
|
|
|
|
else
|
|
|
|
git clone "https://github.com/ansible/ansible.git" "${ansible_dir}"
|
|
|
|
fi
|
|
|
|
# FIXME Revert any files left over from a previous run
|
|
|
|
|
|
|
|
# Ensure we have the correct branch and submodules checked out
|
|
|
|
git -C "${ansible_dir}" checkout "${branch}"
|
|
|
|
git -C "${ansible_dir}" submodule update --init
|
|
|
|
|
|
|
|
##
|
|
|
|
# Have we already ran tests on this commit
|
|
|
|
checkout_sha="$(git -C "${ansible_dir}" rev-parse HEAD )"
|
|
|
|
echo "${checkout_sha}"
|
|
|
|
|
|
|
|
# Check against existing sha
|
|
|
|
if [ -e "${branch_dir}/last-tested.sha" ]; then
|
|
|
|
if [ "x${checkout_sha}" = "x$(cat "${branch_dir}/last-tested.sha")" ]; then
|
|
|
|
echo "SKIPPING: $branch '${checkout_sha}' Has already been tested"
|
|
|
|
continue # to the next branch
|
|
|
|
fi
|
|
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
echo "INFO $branch which sha1 of ${checkout_sha} has not been tested yet"
|
|
|
|
echo "${checkout_sha}" > "${branch_dir}/last-tested.sha"
|
|
|
|
logdir_for_this_run="${log_root}/${branch}/${platform}/${checkout_sha}"
|
|
|
|
mkdir -p "${logdir_for_this_run}"
|
|
|
|
|
|
|
|
echo "env-setup..."
|
|
|
|
source "${ansible_dir}/hacking/env-setup"
|
|
|
|
ansible_exit_value=0
|
|
|
|
cd "${ansible_dir}/test/integration"
|
|
|
|
echo "Running Tests..."
|
|
|
|
echo "Logs will be written to: ${log_root}/results.html"
|
|
|
|
ansible-playbook --version > "${logdir_for_this_run}/ansible.log" 2>&1
|
|
|
|
ANSIBLE_FORCE_COLOR=1 ANSIBLE_ROLES_PATH=targets time -p ansible-playbook \
|
|
|
|
-vvv \
|
|
|
|
-i ${inventory} \
|
|
|
|
"${platform}.yaml" >> "${logdir_for_this_run}/ansible.log" 2>&1 || ansible_exit_value=$?
|
|
|
|
echo "Ansible exited with: ${ansible_exit_value}"
|
|
|
|
|
|
|
|
###
|
|
|
|
# Format logs
|
|
|
|
|
|
|
|
# Generate HTML version
|
|
|
|
ansi2html < "${logdir_for_this_run}/ansible.log" > "${logdir_for_this_run}/ansible.html"
|
|
|
|
|
|
|
|
# Strip escape characters
|
|
|
|
sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g" "${logdir_for_this_run}/ansible.log" > "${logdir_for_this_run}/ansible.txt"
|
|
|
|
|
|
|
|
# Write row to HTML table
|
|
|
|
# This is horrible, though it gives us a basic table of results
|
|
|
|
# It abuses the fact that we don't *have* to have "</tbody></table></body></html>
|
|
|
|
|
|
|
|
# Assume tests are failing unless they pass.
|
|
|
|
# In the future we could look up the exit value to detect the difference between
|
|
|
|
# failing test and machine not reachable
|
|
|
|
result_cell="<td bgcolor='red'>${ansible_exit_value}</td>"
|
|
|
|
if [ "${ansible_exit_value}" -eq "0" ]; then
|
|
|
|
result_cell="<td bgcolor='green'>${ansible_exit_value}</td>"
|
|
|
|
fi
|
|
|
|
|
|
|
|
gh_link="<a href='https://github.com/ansible/ansible/commits/${checkout_sha}'>${checkout_sha}</a>"
|
|
|
|
|
|
|
|
echo "<tr><td><a href='${branch}/${platform}/${checkout_sha}/ansible.html'>$(date -R)</a></td><td>${branch}</td><td>${gh_link}</td><td>${platform}</td>${result_cell}</tr>" >> "${log_root}/results.html"
|
|
|
|
if [ "${ansible_exit_value}" -ne "0" ]; then
|
|
|
|
# Display the last few lines of the log
|
|
|
|
tail -n 20 "${logdir_for_this_run}/ansible.log"
|
|
|
|
fi
|
|
|
|
|
|
|
|
echo "Logs written to: ${logdir_for_this_run}"
|
|
|
|
|
|
|
|
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
validate_tools() {
|
|
|
|
# FIXME
|
|
|
|
echo "In validate_tools"
|
|
|
|
if ! [ -x "$(command -v git)" ]; then
|
|
|
|
eexit "'git' is not installed." >&2
|
|
|
|
fi
|
|
|
|
if ! [ -x "$(command -v ansi2html)" ]; then
|
|
|
|
eexit "'ansi2html' is not installed. Please install with 'sudo pip install ansi2html'" >&2
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
upload_to_s3() {
|
|
|
|
# FIXME
|
|
|
|
echo "In upload_to_s3"
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
lock() {
|
|
|
|
local prefix=$1
|
|
|
|
local fd=${2:-$LOCK_FD}
|
|
|
|
local lock_file=$LOCKFILE_DIR/$prefix.lock
|
|
|
|
|
|
|
|
# create lock file
|
|
|
|
eval "exec $fd>$lock_file"
|
|
|
|
|
|
|
|
# acquire the lock
|
|
|
|
flock -n "${fd}" \
|
|
|
|
&& return 0 \
|
|
|
|
|| return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
eexit() {
|
|
|
|
echo "$1"
|
|
|
|
exit 1
|
|
|
|
}
|
|
|
|
|
|
|
|
# Log everything of interest to syslog and to disk
|
|
|
|
# Based on https://nicolaw.uk/#BashScriptDebugSyslog
|
|
|
|
|
|
|
|
exec > >(2>&-;logger -s -t "$PROG[$$]" -p user.info 2>&1) 2> >(logger -s -t "$PROG[$$]" -p user.error)
|
|
|
|
|
|
|
|
ls
|
|
|
|
ps >&2
|
|
|
|
|
|
|
|
main "$@"
|