Fixed: Smarter application update completed message

Closes #1864
pull/999/merge
Mark McDowall 7 years ago
parent f8d5f1fc94
commit e97e13e897
No known key found for this signature in database
GPG Key ID: D4CEFA9A718052E0

@ -1,121 +1,211 @@
//using System; using System;
//using System.Collections.Generic; using System.Collections.Concurrent;
//using Moq; using System.Collections.Generic;
//using NUnit.Framework; using System.Threading;
//using NzbDrone.Common; using Moq;
//using NzbDrone.Core.Messaging.Commands; using NUnit.Framework;
//using NzbDrone.Core.Messaging.Commands.Tracking; using NzbDrone.Common;
//using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Lifecycle;
//using NzbDrone.Test.Common; using NzbDrone.Core.Messaging.Commands;
// using NzbDrone.Core.Messaging.Events;
//namespace NzbDrone.Core.Test.Messaging.Commands using NzbDrone.Test.Common;
//{
// [TestFixture] namespace NzbDrone.Core.Test.Messaging.Commands
// public class CommandExecutorFixture : TestBase<CommandExecutor> {
// { [TestFixture]
// private Mock<IExecute<CommandA>> _executorA; public class CommandExecutorFixture : TestBase<CommandExecutor>
// private Mock<IExecute<CommandB>> _executorB; {
// private BlockingCollection<CommandModel> _commandQueue;
// [SetUp] private Mock<IExecute<CommandA>> _executorA;
// public void Setup() private Mock<IExecute<CommandB>> _executorB;
// { private bool _commandExecuted = false;
// _executorA = new Mock<IExecute<CommandA>>();
// _executorB = new Mock<IExecute<CommandB>>(); [SetUp]
// public void Setup()
// Mocker.GetMock<IServiceFactory>() {
// .Setup(c => c.Build(typeof(IExecute<CommandA>))) _executorA = new Mock<IExecute<CommandA>>();
// .Returns(_executorA.Object); _executorB = new Mock<IExecute<CommandB>>();
//
// Mocker.GetMock<IServiceFactory>() Mocker.GetMock<IServiceFactory>()
// .Setup(c => c.Build(typeof(IExecute<CommandB>))) .Setup(c => c.Build(typeof(IExecute<CommandA>)))
// .Returns(_executorB.Object); .Returns(_executorA.Object);
//
// Mocker.GetMock<IServiceFactory>()
// Mocker.GetMock<ITrackCommands>() .Setup(c => c.Build(typeof(IExecute<CommandB>)))
// .Setup(c => c.FindExisting(It.IsAny<Command>())) .Returns(_executorB.Object);
// .Returns<Command>(null); }
// }
// private void GivenCommandQueue()
// [Test] {
// public void should_publish_command_to_executor() _commandQueue = new BlockingCollection<CommandModel>(new CommandQueue());
// {
// var commandA = new CommandA(); Mocker.GetMock<IManageCommandQueue>()
// .Setup(s => s.Queue(It.IsAny<CancellationToken>()))
// Subject.Push(commandA); .Returns(_commandQueue.GetConsumingEnumerable);
// }
// _executorA.Verify(c => c.Execute(commandA), Times.Once());
// } private void WaitForExecution(CommandModel commandModel)
// {
// [Test] Mocker.GetMock<IManageCommandQueue>()
// public void should_publish_command_by_with_optional_arg_using_name() .Setup(s => s.Complete(It.Is<CommandModel>(c => c == commandModel), It.IsAny<string>()))
// { .Callback(() => _commandExecuted = true);
// Mocker.GetMock<IServiceFactory>().Setup(c => c.GetImplementations(typeof(Command)))
// .Returns(new List<Type> { typeof(CommandA), typeof(CommandB) }); Mocker.GetMock<IManageCommandQueue>()
// .Setup(s => s.Fail(It.Is<CommandModel>(c => c == commandModel), It.IsAny<string>(), It.IsAny<Exception>()))
// Subject.Push(typeof(CommandA).FullName); .Callback(() => _commandExecuted = true);
// _executorA.Verify(c => c.Execute(It.IsAny<CommandA>()), Times.Once());
// } while (!_commandExecuted)
// {
// Thread.Sleep(100);
// [Test] }
// public void should_not_publish_to_incompatible_executor()
// { var t1 = 1;
// var commandA = new CommandA(); }
//
// Subject.Push(commandA); [Test]
// public void should_start_executor_threads()
// _executorA.Verify(c => c.Execute(commandA), Times.Once()); {
// _executorB.Verify(c => c.Execute(It.IsAny<CommandB>()), Times.Never()); Subject.Handle(new ApplicationStartedEvent());
// }
// Mocker.GetMock<IManageCommandQueue>()
// [Test] .Verify(v => v.Queue(It.IsAny<CancellationToken>()), Times.AtLeastOnce());
// public void broken_executor_should_throw_the_exception() }
// {
// var commandA = new CommandA(); [Test]
// public void should_execute_on_executor()
// _executorA.Setup(c => c.Execute(It.IsAny<CommandA>())) {
// .Throws(new NotImplementedException()); GivenCommandQueue();
// var commandA = new CommandA();
// Assert.Throws<NotImplementedException>(() => Subject.Push(commandA)); var commandModel = new CommandModel
// } {
// Body = commandA
// };
// [Test]
// public void broken_executor_should_publish_executed_event() Subject.Handle(new ApplicationStartedEvent());
// { _commandQueue.Add(commandModel);
// var commandA = new CommandA();
// WaitForExecution(commandModel);
// _executorA.Setup(c => c.Execute(It.IsAny<CommandA>()))
// .Throws(new NotImplementedException()); _executorA.Verify(c => c.Execute(commandA), Times.Once());
// }
// Assert.Throws<NotImplementedException>(() => Subject.Push(commandA));
// [Test]
// VerifyEventPublished<CommandExecutedEvent>(); public void should_not_execute_on_incompatible_executor()
// } {
// GivenCommandQueue();
// [Test] var commandA = new CommandA();
// public void should_publish_executed_event_on_success() var commandModel = new CommandModel
// { {
// var commandA = new CommandA(); Body = commandA
// Subject.Push(commandA); };
//
// VerifyEventPublished<CommandExecutedEvent>(); Subject.Handle(new ApplicationStartedEvent());
// } _commandQueue.Add(commandModel);
// }
// WaitForExecution(commandModel);
// public class CommandA : Command
// { _executorA.Verify(c => c.Execute(commandA), Times.Once());
// public CommandA(int id = 0) _executorB.Verify(c => c.Execute(It.IsAny<CommandB>()), Times.Never());
// { }
// }
// } [Test]
// public void broken_executor_should_publish_executed_event()
// public class CommandB : Command {
// { GivenCommandQueue();
// var commandA = new CommandA();
// public CommandB() var commandModel = new CommandModel
// { {
// } Body = commandA
// } };
//
//} _executorA.Setup(s => s.Execute(It.IsAny<CommandA>()))
.Throws(new NotImplementedException());
Subject.Handle(new ApplicationStartedEvent());
_commandQueue.Add(commandModel);
WaitForExecution(commandModel);
VerifyEventPublished<CommandExecutedEvent>();
ExceptionVerification.ExpectedErrors(1);
}
[Test]
public void should_publish_executed_event_on_success()
{
GivenCommandQueue();
var commandA = new CommandA();
var commandModel = new CommandModel
{
Body = commandA
};
Subject.Handle(new ApplicationStartedEvent());
_commandQueue.Add(commandModel);
WaitForExecution(commandModel);
VerifyEventPublished<CommandExecutedEvent>();
}
[Test]
public void should_use_completion_message()
{
GivenCommandQueue();
var commandA = new CommandA();
var commandModel = new CommandModel
{
Body = commandA
};
Subject.Handle(new ApplicationStartedEvent());
_commandQueue.Add(commandModel);
WaitForExecution(commandModel);
Mocker.GetMock<IManageCommandQueue>()
.Setup(s => s.Complete(It.Is<CommandModel>(c => c == commandModel), commandA.CompletionMessage))
.Callback(() => _commandExecuted = true);
}
[Test]
public void should_use_last_progress_message_if_completion_message_is_null()
{
GivenCommandQueue();
var commandA = new CommandA();
var commandModel = new CommandModel
{
Body = commandA,
Message = "Do work"
};
Subject.Handle(new ApplicationStartedEvent());
_commandQueue.Add(commandModel);
WaitForExecution(commandModel);
Mocker.GetMock<IManageCommandQueue>()
.Setup(s => s.Complete(It.Is<CommandModel>(c => c == commandModel), commandModel.Message))
.Callback(() => _commandExecuted = true);
}
}
public class CommandA : Command
{
public CommandA(int id = 0)
{
}
}
public class CommandB : Command
{
public CommandB()
{
}
public override string CompletionMessage => null;
}
}

@ -1,4 +1,4 @@
using System; using System;
using System.Threading; using System.Threading;
using NLog; using NLog;
using NzbDrone.Common; using NzbDrone.Common;
@ -76,7 +76,7 @@ namespace NzbDrone.Core.Messaging.Commands
handler.Execute(command); handler.Execute(command);
_commandQueueManager.Complete(commandModel, command.CompletionMessage); _commandQueueManager.Complete(commandModel, command.CompletionMessage ?? commandModel.Message);
} }
catch (CommandFailedException ex) catch (CommandFailedException ex)
{ {

@ -35,7 +35,7 @@ namespace NzbDrone.Core.Messaging.Commands
private readonly Logger _logger; private readonly Logger _logger;
private readonly ICached<CommandModel> _commandCache; private readonly ICached<CommandModel> _commandCache;
private readonly BlockingCollection<CommandModel> _commandQueue; private readonly BlockingCollection<CommandModel> _commandQueue;
public CommandQueueManager(ICommandRepository repo, public CommandQueueManager(ICommandRepository repo,
IServiceFactory serviceFactory, IServiceFactory serviceFactory,

@ -6,6 +6,6 @@ namespace NzbDrone.Core.Update.Commands
{ {
public override bool SendUpdatesToClient => true; public override bool SendUpdatesToClient => true;
public override string CompletionMessage => "Restarting Sonarr to apply updates"; public override string CompletionMessage => null;
} }
} }

@ -199,19 +199,20 @@ namespace NzbDrone.Core.Update
if (latestAvailable == null) if (latestAvailable == null)
{ {
_logger.ProgressDebug("No update available."); _logger.ProgressDebug("No update available");
return; return;
} }
if (OsInfo.IsNotWindows && !_configFileProvider.UpdateAutomatically && message.Trigger != CommandTrigger.Manual) if (OsInfo.IsNotWindows && !_configFileProvider.UpdateAutomatically && message.Trigger != CommandTrigger.Manual)
{ {
_logger.ProgressDebug("Auto-update not enabled, not installing available update."); _logger.ProgressDebug("Auto-update not enabled, not installing available update");
return; return;
} }
try try
{ {
InstallUpdate(latestAvailable); InstallUpdate(latestAvailable);
_logger.ProgressDebug("Restarting Sonarr to apply updates");
} }
catch (UpdateFolderNotWritableException ex) catch (UpdateFolderNotWritableException ex)
{ {

Loading…
Cancel
Save