mirror of
https://github.com/offen/docker-volume-backup.git
synced 2024-12-25 10:00:22 +01:00
Ensure end time is recorded for unsuccessful runs too (#62)
* Ensure end time is also recorded for unsuccessful runs * Clean up integration tests
This commit is contained in:
parent
0e248010a8
commit
3e17d1b123
@ -88,8 +88,6 @@ func main() {
|
||||
s.must(s.encryptBackup())
|
||||
s.must(s.copyBackup())
|
||||
s.must(s.pruneOldBackups())
|
||||
s.stats.EndTime = time.Now()
|
||||
s.stats.TookTime = s.stats.EndTime.Sub(s.stats.EndTime)
|
||||
}
|
||||
|
||||
// script holds all the stateful information required to orchestrate a
|
||||
@ -191,8 +189,6 @@ type Config struct {
|
||||
WebdavPassword string `split_words:"true"`
|
||||
}
|
||||
|
||||
var msgBackupFailed = "backup run failed"
|
||||
|
||||
// newScript creates all resources needed for the script to perform actions against
|
||||
// remote resources like the Docker engine or remote storage locations. All
|
||||
// reading from env vars or other configuration sources is expected to happen
|
||||
@ -214,6 +210,12 @@ func newScript() (*script, error) {
|
||||
},
|
||||
}
|
||||
|
||||
s.registerHook(hookLevelPlumbing, func(error) error {
|
||||
s.stats.EndTime = time.Now()
|
||||
s.stats.TookTime = s.stats.EndTime.Sub(s.stats.EndTime)
|
||||
return nil
|
||||
})
|
||||
|
||||
if err := envconfig.Process("", s.c); err != nil {
|
||||
return nil, fmt.Errorf("newScript: failed to process configuration values: %w", err)
|
||||
}
|
||||
|
@ -7,6 +7,8 @@ cd $(dirname $0)
|
||||
docker network create test_network
|
||||
docker volume create backup_data
|
||||
docker volume create app_data
|
||||
# This volume is created to test whether empty directories are handled
|
||||
# correctly. It is not supposed to hold any data.
|
||||
docker volume create empty_data
|
||||
|
||||
docker run -d \
|
||||
@ -48,8 +50,10 @@ docker run --rm -it \
|
||||
-v backup_data:/data alpine \
|
||||
ash -c 'tar -xvf /data/backup/test.tar.gz && test -f /backup/app_data/offen.db && test -d /backup/empty_data'
|
||||
|
||||
echo "[TEST:PASS] Found relevant files in untared backup."
|
||||
echo "[TEST:PASS] Found relevant files in untared remote backup."
|
||||
|
||||
# This test does not stop containers during backup. This is happening on
|
||||
# purpose in order to cover this setup as well.
|
||||
if [ "$(docker ps -q | wc -l)" != "2" ]; then
|
||||
echo "[TEST:FAIL] Expected all containers to be running post backup, instead seen:"
|
||||
docker ps
|
||||
|
@ -9,9 +9,20 @@ mkdir -p local
|
||||
docker-compose up -d
|
||||
sleep 5
|
||||
|
||||
# A symlink for a known file in the volume is created so the test can check
|
||||
# whether symlinks are preserved on backup.
|
||||
docker-compose exec offen ln -s /var/opt/offen/offen.db /var/opt/offen/db.link
|
||||
docker-compose exec backup backup
|
||||
|
||||
sleep 5
|
||||
if [ "$(docker-compose ps -q | wc -l)" != "4" ]; then
|
||||
echo "[TEST:FAIL] Expected all containers to be running post backup, instead seen:"
|
||||
docker-compose ps
|
||||
exit 1
|
||||
fi
|
||||
echo "[TEST:PASS] All containers running post backup."
|
||||
|
||||
|
||||
docker run --rm -it \
|
||||
-v compose_minio_backup_data:/minio_data \
|
||||
-v compose_webdav_backup_data:/webdav_data alpine \
|
||||
@ -19,23 +30,17 @@ docker run --rm -it \
|
||||
echo 1234secret | gpg -d --pinentry-mode loopback --passphrase-fd 0 --yes /minio_data/backup/test-hostnametoken.tar.gz.gpg > /tmp/test-hostnametoken.tar.gz && tar -xf /tmp/test-hostnametoken.tar.gz -C /tmp && test -f /tmp/backup/app_data/offen.db && \
|
||||
echo 1234secret | gpg -d --pinentry-mode loopback --passphrase-fd 0 --yes /webdav_data/data/my/new/path/test-hostnametoken.tar.gz.gpg > /tmp/test-hostnametoken.tar.gz && tar -xf /tmp/test-hostnametoken.tar.gz -C /tmp && test -f /tmp/backup/app_data/offen.db'
|
||||
|
||||
echo "[TEST:PASS] Found relevant files in untared remote backups."
|
||||
echo "[TEST:PASS] Found relevant files in decrypted and untared remote backups."
|
||||
|
||||
test -L ./local/test-hostnametoken.latest.tar.gz.gpg
|
||||
echo 1234secret | gpg -d --yes --passphrase-fd 0 ./local/test-hostnametoken.tar.gz.gpg > ./local/decrypted.tar.gz
|
||||
tar -xf ./local/decrypted.tar.gz -C /tmp && test -f /tmp/backup/app_data/offen.db
|
||||
rm ./local/decrypted.tar.gz
|
||||
test -L /tmp/backup/app_data/db.link
|
||||
|
||||
echo "[TEST:PASS] Found relevant files in untared local backup."
|
||||
echo "[TEST:PASS] Found relevant files in decrypted and untared local backup."
|
||||
|
||||
if [ "$(docker-compose ps -q | wc -l)" != "4" ]; then
|
||||
echo "[TEST:FAIL] Expected all containers to be running post backup, instead seen:"
|
||||
docker-compose ps
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[TEST:PASS] All containers running post backup."
|
||||
test -L ./local/test-hostnametoken.latest.tar.gz.gpg
|
||||
echo "[TEST:PASS] Found symlink to latest version in local backup."
|
||||
|
||||
# The second part of this test checks if backups get deleted when the retention
|
||||
# is set to 0 days (which it should not as it would mean all backups get deleted)
|
||||
@ -56,8 +61,8 @@ echo "[TEST:PASS] Remote backups have not been deleted."
|
||||
if [ "$(find ./local -type f | wc -l)" != "1" ]; then
|
||||
echo "[TEST:FAIL] Backups should not have been deleted, instead seen:"
|
||||
find ./local -type f
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[TEST:PASS] Local backups have not been deleted."
|
||||
|
||||
docker-compose down --volumes
|
||||
|
@ -9,7 +9,7 @@ services:
|
||||
BACKUP_CRON_EXPRESSION: 0 0 5 31 2 ?
|
||||
BACKUP_PRUNING_PREFIX: test
|
||||
NOTIFICATION_LEVEL: info
|
||||
NOTIFICATION_URLS: gotify://gotify/${GOTIFY_TOKEN}?disableTLS=true
|
||||
NOTIFICATION_URLS: ${NOTIFICATION_URLS}
|
||||
volumes:
|
||||
- ./local:/archive
|
||||
- app_data:/backup/app_data:ro
|
||||
|
@ -10,49 +10,43 @@ docker-compose up -d
|
||||
sleep 5
|
||||
|
||||
GOTIFY_TOKEN=$(curl -sSLX POST -H 'Content-Type: application/json' -d '{"name":"test"}' http://admin:custom@localhost:8080/application | jq -r '.token')
|
||||
|
||||
docker-compose down
|
||||
|
||||
GOTIFY_TOKEN=$GOTIFY_TOKEN docker-compose up -d
|
||||
|
||||
echo "[TEST:INFO] Set up Gotify application using token $GOTIFY_TOKEN"
|
||||
|
||||
docker-compose exec backup backup
|
||||
|
||||
tar -xf ./local/test.tar.gz -C /tmp && test -f /tmp/backup/app_data/offen.db
|
||||
echo "[TEST:PASS] Found relevant files in untared local backup."
|
||||
|
||||
if [ "$(docker-compose ps -q | wc -l)" != "3" ]; then
|
||||
echo "[TEST:FAIL] Expected all containers to be running post backup, instead seen:"
|
||||
docker-compose ps
|
||||
NUM_MESSAGES=$(curl -sSL http://admin:custom@localhost:8080/message | jq -r '.messages | length')
|
||||
if [ "$NUM_MESSAGES" != 0 ]; then
|
||||
echo "[TEST:FAIL] Expected no notifications to be sent when not configured"
|
||||
exit 1
|
||||
fi
|
||||
echo "[TEST:PASS] No notifications were sent when not configured."
|
||||
|
||||
echo "[TEST:PASS] All containers running post backup."
|
||||
docker-compose down
|
||||
|
||||
MESSAGE=$(curl -sSL http://admin:custom@localhost:8080/message | jq -r '.messages[0]')
|
||||
NOTIFICATION_URLS="gotify://gotify/${GOTIFY_TOKEN}?disableTLS=true" docker-compose up -d
|
||||
|
||||
docker-compose exec backup backup
|
||||
|
||||
case "$MESSAGE" in
|
||||
*"Successful test run, yay!"*)
|
||||
echo "[TEST:PASS] Custom notification title was used"
|
||||
;;
|
||||
*)
|
||||
echo "[TEST:FAIL] Expected custom title to be used in notification, instead seen:"
|
||||
echo $MESSAGE
|
||||
NUM_MESSAGES=$(curl -sSL http://admin:custom@localhost:8080/message | jq -r '.messages | length')
|
||||
if [ "$NUM_MESSAGES" != 1 ]; then
|
||||
echo "[TEST:FAIL] Expected one notifications to be sent when configured"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
echo "[TEST:PASS] Correct number of notifications were sent when configured."
|
||||
|
||||
case "$MESSAGE" in
|
||||
*"Backing up /tmp/test.tar.gz succeeded."*)
|
||||
echo "[TEST:PASS] Custom notification body was used"
|
||||
;;
|
||||
*)
|
||||
echo "[TEST:FAIL] Expected custom body to be used in notification, instead seen:"
|
||||
echo $MESSAGE
|
||||
MESSAGE_TITLE=$(curl -sSL http://admin:custom@localhost:8080/message | jq -r '.messages[0].title')
|
||||
MESSAGE_BODY=$(curl -sSL http://admin:custom@localhost:8080/message | jq -r '.messages[0].message')
|
||||
|
||||
if [ "$MESSAGE_TITLE" != "Successful test run, yay!" ]; then
|
||||
echo "[TEST:FAIL] Unexpected notification title $MESSAGE_TITLE"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
echo "[TEST:PASS] Custom notification title was used."
|
||||
|
||||
if [ "$MESSAGE_BODY" != "Backing up /tmp/test.tar.gz succeeded." ]; then
|
||||
echo "[TEST:FAIL] Unexpected notification body $MESSAGE_BODY"
|
||||
exit 1
|
||||
fi
|
||||
echo "[TEST:PASS] Custom notification body was used."
|
||||
|
||||
docker-compose down --volumes
|
||||
|
@ -29,9 +29,7 @@ if [ "$(docker ps -q | wc -l)" != "5" ]; then
|
||||
docker ps -a
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[TEST:PASS] All containers running post backup."
|
||||
|
||||
docker stack rm test_stack
|
||||
|
||||
docker swarm leave --force
|
||||
|
Loading…
Reference in New Issue
Block a user