Skip to content
Snippets Groups Projects
Commit 6e83d53d authored by Jérôme Charaoui's avatar Jérôme Charaoui
Browse files

[tests] Introduce bats-based testsuite

 - Depends on being run inside vagrant
 - Installs dependencies automatically
 - Environment is fully reset for each test
 - Adds testcases for backupninja and sys handler
 - Docs are missing but will be added

Two tests are currently failing due to two bugs, one of which has gone
unreported.
parent f7fcf060
Branches
No related tags found
No related merge requests found
load common
testaction() {
echo '#!/bin/sh' > "${BATS_TMPDIR}/backup.d/test.sh"
echo "$1 $2" >> "${BATS_TMPDIR}/backup.d/test.sh"
chmod 0750 "${BATS_TMPDIR}/backup.d/test.sh"
}
@test "general: usage information is displayed" {
run backupninja --help
[ "$status" -eq 0 ]
[ "${lines[0]}" = "/usr/sbin/backupninja usage:" ]
}
@test "general: error thrown on bad command-line option" {
run backupninja --foo
[ "$status" -eq 2 ]
[ "${lines[0]}" = "Unknown option --foo" ]
}
@test "general: logfile is created" {
run backupninja -f "${BATS_TMPDIR}/backupninja.conf"
[ "$status" -eq 0 ]
[ -f "${BATS_TMPDIR}/log/backupninja.log" ]
}
@test "general: no backup actions configured is logged" {
run backupninja --test -f "${BATS_TMPDIR}/backupninja.conf"
[ "$status" -eq 0 ]
[ "${lines[0]}" = "Info: No backup actions configured in '${BATS_TMPDIR}/backup.d', run ninjahelper!" ]
}
@test "general: file without suffix in action directory is ignored" {
touch "${BATS_TMPDIR}/backup.d/test"
chmod 0640 "${BATS_TMPDIR}/backup.d/test"
run backupninja -f "${BATS_TMPDIR}/backupninja.conf"
[ "$status" -eq 0 ]
grep -q "Info: Skipping ${BATS_TMPDIR}/backup.d/test" "${BATS_TMPDIR}/log/backupninja.log"
}
@test "permissions: error thrown when backup action is owned by non-root user" {
testaction
chown vagrant: "${BATS_TMPDIR}/backup.d/test.sh"
run backupninja -f "${BATS_TMPDIR}/backupninja.conf"
[ "$status" -eq 2 ]
echo "${lines[0]}" | grep -qe '^Configuration files must be owned by root!'
}
@test "permissions: error thrown when backup action is world readable" {
testaction
chmod 0755 "${BATS_TMPDIR}/backup.d/test.sh"
run backupninja -f "${BATS_TMPDIR}/backupninja.conf"
[ "$status" -eq 2 ]
echo "${lines[0]}" | grep -qe '^Configuration files must not be world writable/readable!'
}
@test "permissions: error thrown when backup action group ownership is bad" {
testaction
chgrp staff "${BATS_TMPDIR}/backup.d/test.sh"
run backupninja --now -f "${BATS_TMPDIR}/backupninja.conf"
[ "$status" -eq 2 ]
echo "${lines[0]}" | grep -qe '^Configuration files must not be writable/readable by group staff!'
}
@test "reports: error report is mailed" {
testaction fatal test_error
run backupninja --now -f "${BATS_TMPDIR}/backupninja.conf" --run "${BATS_TMPDIR}/backup.d/test.sh"
[ "$status" -eq 0 ]
sleep 0.1
grep -q "\*failed\* -- ${BATS_TMPDIR}/backup.d/test.sh" /var/mail/vagrant
}
@test "reports: warning report is mailed" {
testaction warning test_warning
setconfig backupninja.conf reportsuccess no
setconfig backupninja.conf reportwarning yes
run backupninja --now -f "${BATS_TMPDIR}/backupninja.conf" --run "${BATS_TMPDIR}/backup.d/test.sh"
[ "$status" -eq 0 ]
sleep 0.1
grep -q "Warning: test_warning" /var/mail/vagrant
}
@test "reports: success report is mailed" {
testaction
setconfig backupninja.conf reportsuccess yes
run backupninja --now -f "${BATS_TMPDIR}/backupninja.conf" --run "${BATS_TMPDIR}/backup.d/test.sh"
[ "$status" -eq 0 ]
sleep 0.1
grep -q "success -- ${BATS_TMPDIR}/backup.d/test.sh" /var/mail/vagrant
}
@test "reports: success report contains informational messages" {
testaction info test_info
setconfig backupninja.conf reportsuccess yes
setconfig backupninja.conf reportinfo yes
run backupninja --now -f "${BATS_TMPDIR}/backupninja.conf" --run "${BATS_TMPDIR}/backup.d/test.sh"
[ "$status" -eq 0 ]
sleep 0.1
grep -q "Info: test_info" /var/mail/vagrant
}
@test "reports: success report contains disk space info" {
testaction
echo "directory = /" >> "${BATS_TMPDIR}/backup.d/test.sh"
setconfig backupninja.conf reportsuccess yes
setconfig backupninja.conf reportspace yes
run backupninja --now -f "${BATS_TMPDIR}/backupninja.conf" --run "${BATS_TMPDIR}/backup.d/test.sh"
[ "$status" -eq 0 ]
sleep 0.1
grep -q "/dev/sda1" /var/mail/vagrant
}
@test "scheduling: runs when = 'everyday at 01' and time matches" {
testaction info test_info
setconfig backupninja.conf when 'everyday at 01'
run faketime -f '@2018-06-12 01:00:00' backupninja -f "${BATS_TMPDIR}/backupninja.conf"
[ "$status" -eq 0 ]
grep -q "Info: FINISHED: 1 actions run. 0 fatal. 0 error. 0 warning." "${BATS_TMPDIR}/log/backupninja.log"
}
@test "scheduling: skips when = 'everyday at 01' and time is mismatched" {
testaction info test_info
setconfig backupninja.conf when 'everyday at 01'
setconfig backupninja.conf loglevel 5
run faketime -f '@2018-06-12 02:00:00' backupninja -f "${BATS_TMPDIR}/backupninja.conf"
[ "$status" -eq 0 ]
grep -q "Debug: skipping ${BATS_TMPDIR}/backup.d/test.sh because current time does not match everyday at 01" "${BATS_TMPDIR}/log/backupninja.log"
}
@test "scheduling: runs when = 'Tuesday at 04' and time matches" {
testaction info test_info
setconfig backupninja.conf when 'Tuesday at 04'
run faketime -f '@2018-06-10 04:00:00' backupninja -f "${BATS_TMPDIR}/backupninja.conf"
[ "$status" -eq 0 ]
grep -q "Info: FINISHED: 1 actions run. 0 fatal. 0 error. 0 warning." "${BATS_TMPDIR}/log/backupninja.log"
}
@test "scheduling: skips when = 'Tuesday at 04' and time is mismatched" {
testaction info test_info
setconfig backupninja.conf when 'Tuesday at 04'
setconfig backupninja.conf loglevel 5
run faketime -f '@2018-06-13 04:00:00' backupninja -f "${BATS_TMPDIR}/backupninja.conf"
[ "$status" -eq 0 ]
grep -q "Debug: skipping ${BATS_TMPDIR}/backup.d/test.sh because current time does not match Tuesday at 04" "${BATS_TMPDIR}/log/backupninja.log"
}
@test "scheduling: runs when = '1st at 10' and time matches" {
testaction info test_info
setconfig backupninja.conf when '1st at 10'
run faketime -f '@2018-06-01 10:00:00' backupninja -f "${BATS_TMPDIR}/backupninja.conf"
[ "$status" -eq 0 ]
grep -q "Info: FINISHED: 1 actions run. 0 fatal. 0 error. 0 warning." "${BATS_TMPDIR}/log/backupninja.log"
}
@test "scheduling: skips when = '1st at 10' and time is mismatched" {
testaction info test_info
setconfig backupninja.conf when '1st at 10'
setconfig backupninja.conf loglevel 5
run faketime -f '@2018-06-15 10:00:00' backupninja -f "${BATS_TMPDIR}/backupninja.conf"
[ "$status" -eq 0 ]
grep -q "Debug: skipping ${BATS_TMPDIR}/backup.d/test.sh because current time does not match 1st at 10" "${BATS_TMPDIR}/log/backupninja.log"
}
@test "scheduling: runs when = '21 at 09:00' and time matches" {
testaction info test_info
setconfig backupninja.conf when '21 at 09:00'
run faketime -f '@2018-06-21 09:00:00' backupninja -f "${BATS_TMPDIR}/backupninja.conf"
[ "$status" -eq 0 ]
grep -q "Info: FINISHED: 1 actions run. 0 fatal. 0 error. 0 warning." "${BATS_TMPDIR}/log/backupninja.log"
}
@test "scheduling: skips when = '21 at 09:00' and time is mismatched" {
testaction info test_info
setconfig backupninja.conf when '21 at 09:00'
setconfig backupninja.conf loglevel 5
run faketime -f '@2018-06-22 09:00:00' backupninja -f "${BATS_TMPDIR}/backupninja.conf"
[ "$status" -eq 0 ]
grep -q "Debug: skipping ${BATS_TMPDIR}/backup.d/test.sh because current time does not match 21 at 09:00" "${BATS_TMPDIR}/log/backupninja.log"
}
setup() {
# Write a basic config file
cat << EOF > "${BATS_TMPDIR}/backupninja.conf"
when = manual
loglevel = 4
reportemail = root
reportsuccess = yes
reportinfo = no
reportwarning = yes
reportspace = no
reporthost =
reportuser = ninja
reportdirectory = /var/lib/backupninja/reports
admingroup = root
logfile = ${BATS_TMPDIR}/log/backupninja.log
configdirectory = ${BATS_TMPDIR}/backup.d
scriptdirectory = /usr/share/backupninja
libdirectory = /usr/lib/backupninja
usecolors = no
EOF
mkdir "${BATS_TMPDIR}/log" "${BATS_TMPDIR}/backup.d"
chmod 0750 "${BATS_TMPDIR}/backup.d"
}
teardown() {
# Clean up
rm -rf "${BATS_TMPDIR}/backupninja.conf" \
"${BATS_TMPDIR}/log" \
"${BATS_TMPDIR}/backup.d" \
/var/mail/vagrant \
/var/backups/*
}
setconfig() {
if grep -q "$2 =" "${BATS_TMPDIR}/$1"; then
sed -i "s/^$2.*/$2 = $3/" "${BATS_TMPDIR}/$1"
else
echo "$2 = $3/" >> "${BATS_TMPDIR}/$1"
fi
}
apt-get -qq install debconf-utils hwinfo lvm2
load common
sysconfig() {
cat << EOF > "${BATS_TMPDIR}/backup.d/test.sys"
when = manual
packages = no
partitions = no
hardware = no
luksheaders = no
lvm = no
mbr = no
bios = no
EOF
chmod 0640 "${BATS_TMPDIR}/backup.d/test.sys"
}
setup_lvm() {
modprobe brd rd_nr=1 rd_size=4585760 max_part=0
pvcreate /dev/ram0
vgcreate vgtest /dev/ram0
lvcreate -L 50M -n lvtest vgtest /dev/ram0
}
teardown_lvm() {
lvchange -an vgtest/lvtest
lvremove -f vgtest/lvtest
vgremove -f vgtest
pvremove /dev/ram0
modprobe -r brd
}
setup_luks() {
modprobe brd rd_nr=1 rd_size=4585760 max_part=0
cryptsetup -q luksFormat /dev/ram0 <<< 123test
}
teardown_luks() {
modprobe -r brd
}
@test "sys: sysreport" {
sysconfig
run backupninja -f "${BATS_TMPDIR}/backupninja.conf" --now --run "${BATS_TMPDIR}/backup.d/test.sys"
[ "$status" -eq 0 ]
[ -s /var/backups/sysreport.txt ]
grep -q '# Determinding your current hostname:' /var/backups/sysreport.txt
grep -q "Info: FINISHED: 1 actions run. 0 fatal. 0 error. 0 warning." "${BATS_TMPDIR}/log/backupninja.log"
}
@test "sys: packages" {
sysconfig
setconfig 'backup.d/test.sys' packages yes
run backupninja -f "${BATS_TMPDIR}/backupninja.conf" --now --run "${BATS_TMPDIR}/backup.d/test.sys"
[ "$status" -eq 0 ]
grep -q "Info: FINISHED: 1 actions run. 0 fatal. 0 error. 0 warning." "${BATS_TMPDIR}/log/backupninja.log"
[ -s /var/backups/dpkg-selections.txt ]
[ -s /var/backups/debconfsel.txt ]
}
@test "sys: partitions" {
sysconfig
setconfig 'backup.d/test.sys' partitions yes
run backupninja -f "${BATS_TMPDIR}/backupninja.conf" --now --run "${BATS_TMPDIR}/backup.d/test.sys"
[ "$status" -eq 0 ]
[ -s /var/backups/partitions.sda.txt ]
grep -q "Info: FINISHED: 1 actions run. 0 fatal. 0 error. 0 warning." "${BATS_TMPDIR}/log/backupninja.log"
}
@test "sys: hardware" {
sysconfig
setconfig 'backup.d/test.sys' hardware yes
run backupninja -f "${BATS_TMPDIR}/backupninja.conf" --now --run "${BATS_TMPDIR}/backup.d/test.sys"
[ "$status" -eq 0 ]
[ -s /var/backups/hardware.txt ]
grep -q "Info: FINISHED: 1 actions run. 0 fatal. 0 error. 0 warning." "${BATS_TMPDIR}/log/backupninja.log"
}
@test "sys: lvm" {
sysconfig
setconfig 'backup.d/test.sys' lvm yes
setup_lvm
run backupninja -f "${BATS_TMPDIR}/backupninja.conf" --now --run "${BATS_TMPDIR}/backup.d/test.sys"
[ "$status" -eq 0 ]
[ -d /var/backups/lvm ]
[ -s /var/backups/lvm/vgtest ]
grep -q 'contents = "Text Format Volume Group"' "/var/backups/lvm/vgtest"
grep -q "Info: FINISHED: 1 actions run. 0 fatal. 0 error. 0 warning." "${BATS_TMPDIR}/log/backupninja.log"
teardown_lvm
}
@test "sys: luksheaders" {
sysconfig
setconfig 'backup.d/test.sys' luksheaders yes
setup_luks
run backupninja -f "${BATS_TMPDIR}/backupninja.conf" --now --run "${BATS_TMPDIR}/backup.d/test.sys"
[ "$status" -eq 0 ]
file /var/backups/luksheader.ram0.bin | grep -q "LUKS encrypted file"
grep -q "Info: FINISHED: 1 actions run. 0 fatal. 0 error. 0 warning." "${BATS_TMPDIR}/log/backupninja.log"
teardown_luks
}
#!/bin/bash
# A minimal testsuite for backupninja
# This is meant to be run inside a development environment,
# so give the user a chance to bail
if [ ! -d "/vagrant" ]; then
read -p "This doesn't look like a test environment (Vagrant). Continue anyway? " -n 1 -r
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
exit 0
fi
fi
# Are we root?
if [[ "$USER" != "root" ]]; then
echo "Please run the test suite as root."
exit 1
fi
# Is backupninja in $PATH ?
if [ ! "$(which backupninja)" ]; then
echo "Couldn't find 'backupninja', is it installed?"
exit 1
fi
# Install basic test dependencies
apt-get -qq install bats mailutils faketime
# Create a temporary base directory
TMPDIR=$(mktemp -t -d bntest.XXXXXX)
export TMPDIR
# Run actual tests
for t in "$(dirname "$0")"/*.bats; do
echo "# $(basename -s .bats "$t")"
bats "$t"
echo
done
# Clean up
rm -rf "${TMPDIR}"
exit 0
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment