diff --git a/NzbDrone.Common/EnviromentProvider.cs b/NzbDrone.Common/EnviromentProvider.cs index 3680860c0..25b055a84 100644 --- a/NzbDrone.Common/EnviromentProvider.cs +++ b/NzbDrone.Common/EnviromentProvider.cs @@ -63,7 +63,7 @@ namespace NzbDrone.Common } } - + public virtual string StartUpPath { get @@ -92,7 +92,19 @@ namespace NzbDrone.Common var fileLocation = Assembly.GetCallingAssembly().Location; return new FileInfo(fileLocation).CreationTime; } + } + public virtual int NzbDroneProcessIdFromEnviroment + { + get + { + var id = Convert.ToInt32(Environment.GetEnvironmentVariable("NZBDRONE_PID")); + + if (id == 0) + throw new InvalidOperationException("NZBDRONE_PID isn't a valid environment variable."); + + return id; + } } private static bool ContainsIIS(DirectoryInfo dir) diff --git a/NzbDrone.Core/CentralDispatch.cs b/NzbDrone.Core/CentralDispatch.cs index b07df60be..a3336f85e 100644 --- a/NzbDrone.Core/CentralDispatch.cs +++ b/NzbDrone.Core/CentralDispatch.cs @@ -120,7 +120,7 @@ namespace NzbDrone.Core { try { - var pid = Convert.ToInt32(Environment.GetEnvironmentVariable("NZBDRONE_PID")); + var pid = new EnviromentProvider().NzbDroneProcessIdFromEnviroment; Logger.Debug("Attaching to parent process ({0}) for automatic termination.", pid); diff --git a/NzbDrone.Update.Test/NzbDrone.Update.Test.csproj b/NzbDrone.Update.Test/NzbDrone.Update.Test.csproj index 9e69c58c2..8b40d13af 100644 --- a/NzbDrone.Update.Test/NzbDrone.Update.Test.csproj +++ b/NzbDrone.Update.Test/NzbDrone.Update.Test.csproj @@ -67,8 +67,9 @@ - - + + + diff --git a/NzbDrone.Update.Test/ProgramFixture.cs b/NzbDrone.Update.Test/ProgramFixture.cs new file mode 100644 index 000000000..d5421930c --- /dev/null +++ b/NzbDrone.Update.Test/ProgramFixture.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using FluentAssertions; +using Moq; +using NUnit.Framework; +using NzbDrone.Common; +using NzbDrone.Common.Model; +using NzbDrone.Test.Common; +using NzbDrone.Update.Providers; + +namespace NzbDrone.Update.Test +{ + [TestFixture] + public class ProgramFixture : TestBase + { + private Program _program; + + [SetUp] + public void Setup() + { + _program = Mocker.Resolve(); + } + + [Test] + public void should_throw_if_null_passed_in() + { + Assert.Throws(() => _program.Start(null)); + } + + [Test] + public void should_throw_if_less_than_two_arguments_arent_passed_in() + { + Assert.Throws(() => _program.Start(new[] { "" })); + } + + [Test] + public void should_throw_if_more_than_two_arguments_arent_passed_in() + { + Assert.Throws(() => _program.Start(new[] { "", "", "" })); + } + + [TestCase("d", "")] + [TestCase("", "")] + [TestCase("0", "")] + [TestCase("-1", "")] + [TestCase(" ", "")] + [TestCase(".", "")] + public void should_throw_if_first_arg_isnt_an_int(string arg1, string arg2) + { + Assert.Throws(() => _program.Start(new[] { arg1, arg2 })); + } + + [Test] + public void should_call_update_with_corret_path() + { + const string ProcessPath = @"C:\NzbDrone\nzbdrone.exe"; + + Mocker.GetMock().Setup(c => c.GetProcessById(12)) + .Returns(new ProcessInfo() { StartPath = ProcessPath }); + + //Act + _program.Start(new[] { "12", "" }); + + //Assert + Mocker.GetMock().Verify(c => c.Start(ProcessPath), Times.Once()); + } + + + } +} diff --git a/NzbDrone.Update.Test/UpdateProviderStartTest.cs b/NzbDrone.Update.Test/UpdateProviderStartFixture.cs similarity index 99% rename from NzbDrone.Update.Test/UpdateProviderStartTest.cs rename to NzbDrone.Update.Test/UpdateProviderStartFixture.cs index a83e68815..a6ea8e2eb 100644 --- a/NzbDrone.Update.Test/UpdateProviderStartTest.cs +++ b/NzbDrone.Update.Test/UpdateProviderStartFixture.cs @@ -11,7 +11,7 @@ using NzbDrone.Update.Providers; namespace NzbDrone.Update.Test { [TestFixture] - class UpdateProviderStartTest : TestBase + class UpdateProviderStartFixture : TestBase { private const string UPDATE_FOLDER = @"C:\Temp\nzbdrone_update\nzbdrone\"; private const string BACKUP_FOLDER = @"C:\Temp\nzbdrone_update\nzbdrone_backup\"; diff --git a/NzbDrone.Update.Test/UpdateProviderVerifyTest.cs b/NzbDrone.Update.Test/UpdateProviderVerifyFixture.cs similarity index 97% rename from NzbDrone.Update.Test/UpdateProviderVerifyTest.cs rename to NzbDrone.Update.Test/UpdateProviderVerifyFixture.cs index 0ac07b5ca..6ca63d193 100644 --- a/NzbDrone.Update.Test/UpdateProviderVerifyTest.cs +++ b/NzbDrone.Update.Test/UpdateProviderVerifyFixture.cs @@ -12,7 +12,7 @@ using NzbDrone.Update.Providers; namespace NzbDrone.Update.Test { [TestFixture] - class UpdateProviderVerifyTest : TestBase + class UpdateProviderVerifyFixture : TestBase { AutoMoqer mocker = new AutoMoqer(); diff --git a/NzbDrone.Update/Program.cs b/NzbDrone.Update/Program.cs index 01701488b..ecb1830ca 100644 --- a/NzbDrone.Update/Program.cs +++ b/NzbDrone.Update/Program.cs @@ -1,15 +1,78 @@ using System; -using System.Collections.Generic; using System.Linq; -using System.Text; +using NLog; +using NzbDrone.Common; +using NzbDrone.Update.Providers; namespace NzbDrone.Update { - class Program + public class Program { - static void Main(string[] args) + private readonly UpdateProvider _updateProvider; + private readonly ProcessProvider _processProvider; + + private static readonly Logger logger = LogManager.GetCurrentClassLogger(); + + public Program(UpdateProvider updateProvider, ProcessProvider processProvider) { - + _updateProvider = updateProvider; + _processProvider = processProvider; + } + + public static void Main(string[] args) + { + try + { + Console.WriteLine("Starting NzbDrone Update Client"); + + LogConfiguration.RegisterConsoleLogger(LogLevel.Trace); + LogConfiguration.RegisterUdpLogger(); + LogConfiguration.RegisterExceptioneer(); + LogConfiguration.Reload(); + + logger.Info("Initializing update application"); + + var enviromentProvider = new EnviromentProvider(); + var processProvider = new ProcessProvider(); + var serviceProvider = new ServiceProvider(); + var diskProvider = new DiskProvider(); + + var updateProvider = new UpdateProvider(diskProvider, serviceProvider, processProvider, enviromentProvider); + + new Program(updateProvider, processProvider).Start(args); + } + catch (Exception e) + { + logger.Fatal("An error has occurred while applying update.", e); + } + } + + public void Start(string[] args) + { + VerfityArguments(args); + int processId = ParseProcessId(args); + + string appPath = _processProvider.GetProcessById(processId).StartPath; + + logger.Info("Starting update process"); + _updateProvider.Start(appPath); + } + + private int ParseProcessId(string[] args) + { + int id = 0; + if (!Int32.TryParse(args[0], out id) || id <= 0) + { + throw new ArgumentOutOfRangeException("Invalid process id: " + args[0]); + } + + return id; + } + + private void VerfityArguments(string[] args) + { + if (args == null || args.Length != 2) + throw new ArgumentException("Wrong number of parameters were passed in."); } } } diff --git a/NzbDrone.Update/Providers/UpdateProvider.cs b/NzbDrone.Update/Providers/UpdateProvider.cs index 3d8b96742..275419e0e 100644 --- a/NzbDrone.Update/Providers/UpdateProvider.cs +++ b/NzbDrone.Update/Providers/UpdateProvider.cs @@ -14,7 +14,7 @@ namespace NzbDrone.Update.Providers private readonly EnviromentProvider _enviromentProvider; private static readonly Logger logger = LogManager.GetCurrentClassLogger(); - public UpdateProvider(DiskProvider diskProvider,ServiceProvider serviceProvider, + public UpdateProvider(DiskProvider diskProvider, ServiceProvider serviceProvider, ProcessProvider processProvider, EnviromentProvider enviromentProvider) { _diskProvider = diskProvider; @@ -23,6 +23,10 @@ namespace NzbDrone.Update.Providers _enviromentProvider = enviromentProvider; } + public UpdateProvider() + { + } + private void Verify(string targetFolder) { logger.Info("Verifying requirements before update..."); @@ -39,7 +43,7 @@ namespace NzbDrone.Update.Providers } - public void Start(string targetFolder) + public virtual void Start(string targetFolder) { Verify(targetFolder); bool isService = false; @@ -49,7 +53,7 @@ namespace NzbDrone.Update.Providers { if (_serviceProvider.IsServiceRunning(ServiceProvider.NZBDRONE_SERVICE_NAME)) { - isService = true; + isService = true; } _serviceProvider.Stop(ServiceProvider.NZBDRONE_SERVICE_NAME); }