Files
duplicati/Duplicati/UnitTest/DisruptionTests.cs
T

123 lines
5.7 KiB
C#
Raw Normal View History

2019-09-15 10:33:35 -07:00
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Duplicati.Library.Interface;
using Duplicati.Library.Main;
2019-09-15 13:45:43 -07:00
using Duplicati.Library.Main.Database;
2019-09-15 10:33:35 -07:00
using NUnit.Framework;
2019-09-15 15:05:03 -07:00
using Utility = Duplicati.Library.Utility.Utility;
2019-09-15 10:33:35 -07:00
namespace Duplicati.UnitTest
{
public class DisruptionTests : BasicSetupHelper
{
2019-09-15 15:28:53 -07:00
// Files to create in MB.
private readonly int[] fileSizes = {10, 20, 30};
2019-09-15 10:33:35 -07:00
private void ModifySourceFiles()
{
2019-09-15 15:28:53 -07:00
foreach (int size in this.fileSizes)
2019-09-15 10:33:35 -07:00
{
byte[] data = new byte[size * 1024 * 1024];
Random rng = new Random();
rng.NextBytes(data);
File.WriteAllBytes(Path.Combine(this.DATAFOLDER, size + "MB"), data);
}
}
2019-09-15 12:50:31 -07:00
2019-09-15 10:33:35 -07:00
public override void SetUp()
{
base.SetUp();
this.ModifySourceFiles();
}
2019-09-15 12:50:31 -07:00
2019-09-15 10:33:35 -07:00
[Test]
[Category("Disruption")]
public async Task StopAfterCurrentFile()
{
// Choose a dblock size that is small enough so that more than one volume is needed.
2019-09-15 15:59:15 -07:00
Dictionary<string, string> options = new Dictionary<string, string>(this.TestOptions) {["dblock-size"] = "10mb"};
2019-09-15 12:50:31 -07:00
// Run a complete backup.
2019-09-15 10:33:35 -07:00
using (Controller c = new Controller("file://" + this.TARGETFOLDER, options, null))
{
c.Backup(new[] {this.DATAFOLDER});
Assert.AreEqual(1, c.List().Filesets.Count());
2019-09-15 13:45:43 -07:00
Assert.AreEqual(BackupType.FULL_BACKUP, c.List().Filesets.Single(x => x.Version == 0).IsFullBackup);
2019-09-15 12:50:31 -07:00
}
2019-09-15 10:33:35 -07:00
2019-09-15 12:50:31 -07:00
// Modify the source files and interrupt a backup.
this.ModifySourceFiles();
using (Controller c = new Controller("file://" + this.TARGETFOLDER, options, null))
{
2019-09-15 15:55:56 -07:00
// ReSharper disable once AccessToDisposedClosure
2019-09-15 10:33:35 -07:00
Task<IBackupResults> backupTask = Task.Run(() => c.Backup(new[] {this.DATAFOLDER}));
2019-09-15 12:50:31 -07:00
2019-09-15 10:33:35 -07:00
// Block for a small amount of time to allow the ITaskControl to be associated
// with the Controller. Otherwise, the call to Stop will simply be a no-op.
Thread.Sleep(1000);
2019-09-15 12:50:31 -07:00
2019-09-15 10:33:35 -07:00
// If we interrupt the backup, the most recent Fileset should be marked as partial.
c.Stop(true);
2019-09-17 14:16:58 -07:00
await backupTask.ConfigureAwait(false);
2019-09-15 10:33:35 -07:00
Assert.AreEqual(2, c.List().Filesets.Count());
2019-09-15 13:45:43 -07:00
Assert.AreEqual(BackupType.FULL_BACKUP, c.List().Filesets.Single(x => x.Version == 1).IsFullBackup);
Assert.AreEqual(BackupType.PARTIAL_BACKUP, c.List().Filesets.Single(x => x.Version == 0).IsFullBackup);
2019-09-15 10:33:35 -07:00
}
2019-09-15 12:50:31 -07:00
2019-09-15 15:05:03 -07:00
// Restore files from the partial backup set.
Dictionary<string, string> restoreOptions = new Dictionary<string, string>(options) {["restore-path"] = this.RESTOREFOLDER};
using (Controller c = new Controller("file://" + this.TARGETFOLDER, restoreOptions, null))
{
IListResults lastResults = c.List("*");
2019-09-15 15:30:28 -07:00
string[] partialVersionFiles = lastResults.Files.Select(x => x.Path).Where(x => !Utility.IsFolder(x, File.GetAttributes)).ToArray();
Assert.GreaterOrEqual(partialVersionFiles.Length, 1);
2019-09-15 15:05:03 -07:00
c.Restore(partialVersionFiles);
foreach (string filepath in partialVersionFiles)
{
2019-09-15 15:30:28 -07:00
string filename = Path.GetFileName(filepath);
2019-09-15 15:46:13 -07:00
Assert.IsTrue(TestUtils.CompareFiles(filepath, Path.Combine(this.RESTOREFOLDER, filename ?? String.Empty), filename, false));
2019-09-15 15:05:03 -07:00
}
}
// Recreating the database should preserve the backup types.
File.Delete(this.DBFILE);
using (Controller c = new Controller("file://" + this.TARGETFOLDER, options, null))
{
c.Repair();
Assert.AreEqual(2, c.List().Filesets.Count());
2019-09-15 13:45:43 -07:00
Assert.AreEqual(BackupType.FULL_BACKUP, c.List().Filesets.Single(x => x.Version == 1).IsFullBackup);
Assert.AreEqual(BackupType.PARTIAL_BACKUP, c.List().Filesets.Single(x => x.Version == 0).IsFullBackup);
}
2019-09-15 12:50:31 -07:00
// Run a complete backup. Listing the Filesets should omit the previous partial backup.
using (Controller c = new Controller("file://" + this.TARGETFOLDER, options, null))
{
c.Backup(new[] {this.DATAFOLDER});
Assert.AreEqual(2, c.List().Filesets.Count());
2019-09-15 13:45:43 -07:00
Assert.AreEqual(BackupType.FULL_BACKUP, c.List().Filesets.Single(x => x.Version == 1).IsFullBackup);
Assert.AreEqual(BackupType.FULL_BACKUP, c.List().Filesets.Single(x => x.Version == 0).IsFullBackup);
2019-09-15 12:50:31 -07:00
}
2019-09-15 15:31:02 -07:00
// Restore files from the full backup set.
restoreOptions["overwrite"] = "true";
using (Controller c = new Controller("file://" + this.TARGETFOLDER, restoreOptions, null))
{
IListResults lastResults = c.List("*");
string[] fullVersionFiles = lastResults.Files.Select(x => x.Path).Where(x => !Utility.IsFolder(x, File.GetAttributes)).ToArray();
Assert.AreEqual(this.fileSizes.Length, fullVersionFiles.Length);
c.Restore(fullVersionFiles);
foreach (string filepath in fullVersionFiles)
{
string filename = Path.GetFileName(filepath);
2019-09-15 15:46:13 -07:00
Assert.IsTrue(TestUtils.CompareFiles(filepath, Path.Combine(this.RESTOREFOLDER, filename ?? String.Empty), filename, false));
2019-09-15 15:31:02 -07:00
}
}
2019-09-15 10:33:35 -07:00
}
}
}