diff --git a/Duplicati/Library/Modules/Builtin/RunScript.cs b/Duplicati/Library/Modules/Builtin/RunScript.cs index e8188df22..2e67319b5 100644 --- a/Duplicati/Library/Modules/Builtin/RunScript.cs +++ b/Duplicati/Library/Modules/Builtin/RunScript.cs @@ -180,7 +180,25 @@ namespace Duplicati.Library.Modules.Builtin return; ParsedResultType level; - if (result is Exception) + if (result is OperationAbortException oae) + { + switch (oae.AbortReason) + { + case OperationAbortReason.Error: + level = ParsedResultType.Error; + break; + case OperationAbortReason.Normal: + level = ParsedResultType.Success; + break; + case OperationAbortReason.Warning: + level = ParsedResultType.Warning; + break; + default: + level = ParsedResultType.Unknown; + break; + } + } + else if (result is Exception) level = ParsedResultType.Fatal; else if (result != null && result is IBasicResults results) level = results.ParsedResult; diff --git a/Duplicati/UnitTest/RunScriptTests.cs b/Duplicati/UnitTest/RunScriptTests.cs index f6462b895..8f6ca152d 100644 --- a/Duplicati/UnitTest/RunScriptTests.cs +++ b/Duplicati/UnitTest/RunScriptTests.cs @@ -148,6 +148,94 @@ namespace Duplicati.UnitTest } } + [Test] + [Category("Border")] + [TestCase(0)] + [TestCase(1)] + [TestCase(2)] + [TestCase(3)] + [TestCase(4)] + [TestCase(5)] + [TestCase(6)] + public void RunScriptParsedResult(int exitCode) + { + string parsedResultFile = Path.Combine(this.RESTOREFOLDER, "result.txt"); + List customCommands = new List(); + if (Platform.IsClientWindows) + { + customCommands.Add($"echo %DUPLICATI__PARSED_RESULT%>\"{parsedResultFile}\""); + } + else + { + customCommands.Add($"echo $DUPLICATI__PARSED_RESULT>\"{parsedResultFile}\""); + } + + Dictionary options = this.TestOptions; + options["run-script-before"] = this.CreateScript(exitCode); + options["run-script-after"] = this.CreateScript(0, null, null, 0, customCommands); + using (Controller c = new Controller("file://" + this.TARGETFOLDER, options, null)) + { + IBackupResults backupResults = c.Backup(new[] {this.DATAFOLDER}); + + bool expectBackup; + string expectedParsedResult; + switch (exitCode) + { + case 0: // OK, run operation + Assert.AreEqual(0, backupResults.Errors.Count()); + Assert.AreEqual(0, backupResults.Warnings.Count()); + expectBackup = true; + expectedParsedResult = ParsedResultType.Success.ToString(); + break; + case 1: // OK, don't run operation + Assert.AreEqual(0, backupResults.Errors.Count()); + Assert.AreEqual(0, backupResults.Warnings.Count()); + expectBackup = false; + expectedParsedResult = ParsedResultType.Success.ToString(); + break; + case 2: // Warning, run operation + Assert.AreEqual(0, backupResults.Errors.Count()); + Assert.AreEqual(1, backupResults.Warnings.Count()); + expectBackup = true; + expectedParsedResult = ParsedResultType.Warning.ToString(); + break; + case 3: // Warning, don't run operation + Assert.AreEqual(0, backupResults.Errors.Count()); + Assert.AreEqual(1, backupResults.Warnings.Count()); + expectBackup = false; + expectedParsedResult = ParsedResultType.Warning.ToString(); + break; + case 4: // Error, run operation + Assert.AreEqual(1, backupResults.Errors.Count()); + Assert.AreEqual(0, backupResults.Warnings.Count()); + expectBackup = true; + expectedParsedResult = ParsedResultType.Error.ToString(); + break; + default: // Error don't run operation + Assert.AreEqual(1, backupResults.Errors.Count()); + Assert.AreEqual(0, backupResults.Warnings.Count()); + expectBackup = false; + expectedParsedResult = ParsedResultType.Error.ToString(); + break; + } + + IEnumerable targetEntries = Directory.EnumerateFileSystemEntries(this.TARGETFOLDER); + if (expectBackup) + { + // We expect a dblock, dlist, and dindex file. + Assert.AreEqual(3, targetEntries.Count()); + } + else + { + Assert.AreEqual(0, targetEntries.Count()); + } + + string[] lines = File.ReadAllLines(parsedResultFile); + Assert.AreEqual(1, lines.Length); + Assert.AreEqual(expectedParsedResult, lines[0]); + } + } + [Test] [Category("Border")] public void CustomRemoteURL()