From af69436a1e70a2d311c96102206b43e577a2c69d Mon Sep 17 00:00:00 2001 From: Carl Johnsen Date: Wed, 22 Jan 2025 06:10:43 +0100 Subject: [PATCH] Added preliminary unittest for the remote synchronization tool --- Duplicati/Tools/Duplicati.Tools.csproj | 9 ++-- Duplicati/UnitTest/ToolTests.cs | 65 ++++++++++++++++++++++++++ Tools/RemoteSynchronization/Program.cs | 54 +-------------------- 3 files changed, 73 insertions(+), 55 deletions(-) create mode 100644 Duplicati/UnitTest/ToolTests.cs diff --git a/Duplicati/Tools/Duplicati.Tools.csproj b/Duplicati/Tools/Duplicati.Tools.csproj index ecb48b4cc..28ca8eea6 100644 --- a/Duplicati/Tools/Duplicati.Tools.csproj +++ b/Duplicati/Tools/Duplicati.Tools.csproj @@ -5,7 +5,7 @@ Library Copyright © 2024 Team Duplicati, MIT license - + utility-scripts\DuplicatiVerify.ps1 @@ -24,12 +24,15 @@ utility-scripts\pause-resume.py - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/Duplicati/UnitTest/ToolTests.cs b/Duplicati/UnitTest/ToolTests.cs new file mode 100644 index 000000000..a1e48084c --- /dev/null +++ b/Duplicati/UnitTest/ToolTests.cs @@ -0,0 +1,65 @@ +using Duplicati.Library.Common.IO; +using Duplicati.Library.Main; +using NUnit.Framework; +using System; +using System.Collections.Generic; +using System.IO; + +namespace Duplicati.UnitTest +{ + + public class ToolTests : BasicSetupHelper + { + + [Test] + [Category("Tools")] + public void TestRemoteSynchronization() + { + var home = Environment.GetEnvironmentVariable("HOME"); + var base_path = $"{home}/git/duplicati-carl/rsync"; + var l1 = $"{base_path}/l1"; + var l2 = $"{base_path}/l2"; + var l1r = $"{base_path}/l1_restore"; + var l2r = $"{base_path}/l2_restore"; + var backup_path = $"{home}/tmp/adaptivecpp"; + + Dictionary options = new () + { + ["passphrase"] = "1234" + }; + + // Create the directories if they do not exist + foreach (var p in new string[] { base_path, l1, l2, l1r, l2r }) + { + if (!SystemIO.IO_OS.DirectoryExists(p)) + SystemIO.IO_OS.DirectoryCreate(p); + } + + // Backup the first level + using (var c = new Controller($"file://{l1}", options, null)) + { + var results = c.Backup([backup_path]); + Console.WriteLine($"Backed up {results.AddedFiles} files to {l1}"); + } + + // TODO Call the remote synchronization tool + var exe = RemoteSynchronization.Program.Main; + + options["restore-path"] = l1r; + using (var c = new Controller($"file://{l1}", options, null)) + { + var results = c.Restore([Path.Combine(backup_path, "*")]); + Console.WriteLine($"Restored {results.RestoredFiles} files to {options["restore-path"]}"); + } + + // Try to restore the second level + options["restore-path"] = l2r; + using (var c = new Controller($"file://{l2}", options, null)) + { + var results = c.Restore([]); + Console.WriteLine($"Restored {results.RestoredFiles} files to {options["restore-path"]}"); + } + } + } + +} \ No newline at end of file diff --git a/Tools/RemoteSynchronization/Program.cs b/Tools/RemoteSynchronization/Program.cs index c96642a76..6ef22f714 100644 --- a/Tools/RemoteSynchronization/Program.cs +++ b/Tools/RemoteSynchronization/Program.cs @@ -19,7 +19,6 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -using Duplicati.Library.Main; using Duplicati.Library.Common.IO; using Duplicati.Library.Interface; using System; @@ -31,40 +30,12 @@ using System.Threading; namespace RemoteSynchronization { - class Program + public class Program { - static void Main(string[] args) + public static void Main(string[] args) { - // TODO testing start - var home = Environment.GetEnvironmentVariable("HOME"); - var base_path = $"{home}/git/duplicati-carl/rsync"; - var l1 = $"{base_path}/l1"; - var l2 = $"{base_path}/l2"; - var l1r = $"{base_path}/l1_restore"; - var l2r = $"{base_path}/l2_restore"; - var backup_path = $"{home}/tmp/adaptivecpp"; - Dictionary options = new (){ - ["passphrase"] = "1234" - }; - // Create the directories if they do not exist - foreach (var p in new string[] { base_path, l1, l2, l1r, l2r }) - { - if (!SystemIO.IO_OS.DirectoryExists(p)) - SystemIO.IO_OS.DirectoryCreate(p); - } - - // Backup the first level - using (var c = new Controller($"file://{l1}", options, null)) - { - var results = c.Backup([backup_path]); - Console.WriteLine($"Backed up {results.AddedFiles} files to {l1}"); - } - - // TODO testing end - - // Sync the first level to the second level using (var b1 = Duplicati.Library.DynamicLoader.BackendLoader.GetBackend($"file://{l1}", options)) { var b1s = b1 as IStreamingBackend; @@ -80,29 +51,8 @@ namespace RemoteSynchronization Console.WriteLine($"Copied {copied} files from {l1} to {l2}"); } } - - // TODO testing start - // Try to restore the first level - options["restore-path"] = l1r; - using (var c = new Controller($"file://{l1}", options, null)) - { - var results = c.Restore([Path.Combine(backup_path, "*")]); - Console.WriteLine($"Restored {results.RestoredFiles} files to {options["restore-path"]}"); - } - - // Try to restore the second level - options["restore-path"] = l2r; - using (var c = new Controller($"file://{l2}", options, null)) - { - var results = c.Restore([]); - Console.WriteLine($"Restored {results.RestoredFiles} files to {options["restore-path"]}"); - } - // TODO testing end } - // TODO check whether a backend is empty - // TODO check whether the backend files are consistent: src.files.count >= dst.files.count - // TODO handle files deleted from src, which should also be deleted in dst // TODO maximum retention?: don't delete files, only rename old ones. // TODO have concurrency parameters: uploaders, downloaders // TODO low memory mode, where things aren't kept in memory. Maybe utilize SQLite?