mirror of
https://github.com/offen/docker-volume-backup.git
synced 2024-11-25 06:30:29 +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.encryptBackup())
|
||||||
s.must(s.copyBackup())
|
s.must(s.copyBackup())
|
||||||
s.must(s.pruneOldBackups())
|
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
|
// script holds all the stateful information required to orchestrate a
|
||||||
@ -191,8 +189,6 @@ type Config struct {
|
|||||||
WebdavPassword string `split_words:"true"`
|
WebdavPassword string `split_words:"true"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var msgBackupFailed = "backup run failed"
|
|
||||||
|
|
||||||
// newScript creates all resources needed for the script to perform actions against
|
// newScript creates all resources needed for the script to perform actions against
|
||||||
// remote resources like the Docker engine or remote storage locations. All
|
// remote resources like the Docker engine or remote storage locations. All
|
||||||
// reading from env vars or other configuration sources is expected to happen
|
// 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 {
|
if err := envconfig.Process("", s.c); err != nil {
|
||||||
return nil, fmt.Errorf("newScript: failed to process configuration values: %w", err)
|
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 network create test_network
|
||||||
docker volume create backup_data
|
docker volume create backup_data
|
||||||
docker volume create app_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 volume create empty_data
|
||||||
|
|
||||||
docker run -d \
|
docker run -d \
|
||||||
@ -48,8 +50,10 @@ docker run --rm -it \
|
|||||||
-v backup_data:/data alpine \
|
-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'
|
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
|
if [ "$(docker ps -q | wc -l)" != "2" ]; then
|
||||||
echo "[TEST:FAIL] Expected all containers to be running post backup, instead seen:"
|
echo "[TEST:FAIL] Expected all containers to be running post backup, instead seen:"
|
||||||
docker ps
|
docker ps
|
||||||
|
@ -9,9 +9,20 @@ mkdir -p local
|
|||||||
docker-compose up -d
|
docker-compose up -d
|
||||||
sleep 5
|
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 offen ln -s /var/opt/offen/offen.db /var/opt/offen/db.link
|
||||||
docker-compose exec backup backup
|
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 \
|
docker run --rm -it \
|
||||||
-v compose_minio_backup_data:/minio_data \
|
-v compose_minio_backup_data:/minio_data \
|
||||||
-v compose_webdav_backup_data:/webdav_data alpine \
|
-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 /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 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
|
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
|
tar -xf ./local/decrypted.tar.gz -C /tmp && test -f /tmp/backup/app_data/offen.db
|
||||||
rm ./local/decrypted.tar.gz
|
rm ./local/decrypted.tar.gz
|
||||||
test -L /tmp/backup/app_data/db.link
|
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
|
test -L ./local/test-hostnametoken.latest.tar.gz.gpg
|
||||||
echo "[TEST:FAIL] Expected all containers to be running post backup, instead seen:"
|
echo "[TEST:PASS] Found symlink to latest version in local backup."
|
||||||
docker-compose ps
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "[TEST:PASS] All containers running post backup."
|
|
||||||
|
|
||||||
# The second part of this test checks if backups get deleted when the retention
|
# 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)
|
# 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
|
if [ "$(find ./local -type f | wc -l)" != "1" ]; then
|
||||||
echo "[TEST:FAIL] Backups should not have been deleted, instead seen:"
|
echo "[TEST:FAIL] Backups should not have been deleted, instead seen:"
|
||||||
find ./local -type f
|
find ./local -type f
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "[TEST:PASS] Local backups have not been deleted."
|
echo "[TEST:PASS] Local backups have not been deleted."
|
||||||
|
|
||||||
docker-compose down --volumes
|
docker-compose down --volumes
|
||||||
|
@ -9,7 +9,7 @@ services:
|
|||||||
BACKUP_CRON_EXPRESSION: 0 0 5 31 2 ?
|
BACKUP_CRON_EXPRESSION: 0 0 5 31 2 ?
|
||||||
BACKUP_PRUNING_PREFIX: test
|
BACKUP_PRUNING_PREFIX: test
|
||||||
NOTIFICATION_LEVEL: info
|
NOTIFICATION_LEVEL: info
|
||||||
NOTIFICATION_URLS: gotify://gotify/${GOTIFY_TOKEN}?disableTLS=true
|
NOTIFICATION_URLS: ${NOTIFICATION_URLS}
|
||||||
volumes:
|
volumes:
|
||||||
- ./local:/archive
|
- ./local:/archive
|
||||||
- app_data:/backup/app_data:ro
|
- app_data:/backup/app_data:ro
|
||||||
|
@ -10,49 +10,43 @@ docker-compose up -d
|
|||||||
sleep 5
|
sleep 5
|
||||||
|
|
||||||
GOTIFY_TOKEN=$(curl -sSLX POST -H 'Content-Type: application/json' -d '{"name":"test"}' http://admin:custom@localhost:8080/application | jq -r '.token')
|
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"
|
echo "[TEST:INFO] Set up Gotify application using token $GOTIFY_TOKEN"
|
||||||
|
|
||||||
docker-compose exec backup backup
|
docker-compose exec backup backup
|
||||||
|
|
||||||
tar -xf ./local/test.tar.gz -C /tmp && test -f /tmp/backup/app_data/offen.db
|
NUM_MESSAGES=$(curl -sSL http://admin:custom@localhost:8080/message | jq -r '.messages | length')
|
||||||
echo "[TEST:PASS] Found relevant files in untared local backup."
|
if [ "$NUM_MESSAGES" != 0 ]; then
|
||||||
|
echo "[TEST:FAIL] Expected no notifications to be sent when not configured"
|
||||||
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
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
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
|
NUM_MESSAGES=$(curl -sSL http://admin:custom@localhost:8080/message | jq -r '.messages | length')
|
||||||
*"Successful test run, yay!"*)
|
if [ "$NUM_MESSAGES" != 1 ]; then
|
||||||
echo "[TEST:PASS] Custom notification title was used"
|
echo "[TEST:FAIL] Expected one notifications to be sent when configured"
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "[TEST:FAIL] Expected custom title to be used in notification, instead seen:"
|
|
||||||
echo $MESSAGE
|
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
fi
|
||||||
esac
|
echo "[TEST:PASS] Correct number of notifications were sent when configured."
|
||||||
|
|
||||||
case "$MESSAGE" in
|
MESSAGE_TITLE=$(curl -sSL http://admin:custom@localhost:8080/message | jq -r '.messages[0].title')
|
||||||
*"Backing up /tmp/test.tar.gz succeeded."*)
|
MESSAGE_BODY=$(curl -sSL http://admin:custom@localhost:8080/message | jq -r '.messages[0].message')
|
||||||
echo "[TEST:PASS] Custom notification body was used"
|
|
||||||
;;
|
if [ "$MESSAGE_TITLE" != "Successful test run, yay!" ]; then
|
||||||
*)
|
echo "[TEST:FAIL] Unexpected notification title $MESSAGE_TITLE"
|
||||||
echo "[TEST:FAIL] Expected custom body to be used in notification, instead seen:"
|
|
||||||
echo $MESSAGE
|
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
fi
|
||||||
esac
|
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
|
docker-compose down --volumes
|
||||||
|
@ -29,9 +29,7 @@ if [ "$(docker ps -q | wc -l)" != "5" ]; then
|
|||||||
docker ps -a
|
docker ps -a
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "[TEST:PASS] All containers running post backup."
|
echo "[TEST:PASS] All containers running post backup."
|
||||||
|
|
||||||
docker stack rm test_stack
|
docker stack rm test_stack
|
||||||
|
|
||||||
docker swarm leave --force
|
docker swarm leave --force
|
||||||
|
Loading…
Reference in New Issue
Block a user