/* jslint node:true */ /* global it:false */ /* global describe:false */ /* global before:false */ /* global after:false */ 'use strict'; const backups = require('../backups.js'), common = require('./common.js'), expect = require('expect.js'), fs = require('fs'), os = require('os'), path = require('path'), settings = require('../settings.js'), tasks = require('../tasks.js'), timers = require('timers/promises'); describe('backuptask', function () { const { setup, cleanup } = common; before(setup); after(cleanup); describe('fullBackup', function () { let backupInfo1; const backupConfig = { provider: 'filesystem', backupFolder: path.join(os.tmpdir(), 'backupstask-test-filesystem'), format: 'tgz', retentionPolicy: { keepWithinSecs: 10000 }, schedulePattern: '00 00 23 * * *' }; before(async function () { fs.rmSync(backupConfig.backupFolder, { recursive: true, force: true }); await settings.setBackupConfig(backupConfig); }); after(function () { fs.rmSync(backupConfig.backupFolder, { recursive: true, force: true }); }); async function createBackup() { const taskId = await backups.startBackupTask({ username: 'test' }); // eslint-disable-next-line no-constant-condition while (true) { await timers.setTimeout(1000); const p = await tasks.get(taskId); if (p.percent !== 100) continue; if (p.error) throw new Error(`backup failed: ${p.error.message}`); if (!p.result) throw new Error('backup has no result:' + p); const result = await backups.getByIdentifierAndStatePaged(backups.BACKUP_IDENTIFIER_BOX, backups.BACKUP_STATE_NORMAL, 1, 1); if (result.length !== 1) throw new Error('result is not of length 1'); // the task progress and the db entry is set in the worker. wait for 2 seconds for backup lock to get released in parent process await timers.setTimeout(2000); return result[0]; } } it('can backup', async function () { // arch only has maria db which lacks some mysqldump options we need, this is only here to allow running the tests :-/ if (require('child_process').execSync('/usr/bin/mysqldump --version').toString().indexOf('MariaDB') !== -1) { console.log('test skipped because of MariaDB'); return; } const result = await createBackup(); expect(fs.statSync(path.join(backupConfig.backupFolder, 'snapshot/box.tar.gz')).nlink).to.be(2); // hard linked to a rotated backup expect(fs.statSync(path.join(backupConfig.backupFolder, `${result.id}.tar.gz`)).nlink).to.be(2); backupInfo1 = result; }); it('can take another backup', async function () { // arch only has maria db which lacks some mysqldump options we need, this is only here to allow running the tests :-/ if (require('child_process').execSync('/usr/bin/mysqldump --version').toString().indexOf('MariaDB') !== -1) { console.log('test skipped because of MariaDB'); return; } const result = await createBackup(); expect(fs.statSync(path.join(backupConfig.backupFolder, 'snapshot/box.tar.gz')).nlink).to.be(2); // hard linked to a rotated backup expect(fs.statSync(path.join(backupConfig.backupFolder, `${result.id}.tar.gz`)).nlink).to.be(2); // hard linked to new backup expect(fs.statSync(path.join(backupConfig.backupFolder, `${backupInfo1.id}.tar.gz`)).nlink).to.be(1); // not hard linked anymore }); }); });