New: Health check for AppData and Startup folder conflict

pull/4/head
Mark McDowall 11 years ago
parent 519b6debfb
commit ebd13bdda8

@ -0,0 +1,54 @@
using NUnit.Framework;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Core.HealthCheck.Checks;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Test.Common;
namespace NzbDrone.Core.Test.HealthCheck.Checks
{
[TestFixture]
public class AppDataLocationFixture : CoreTest<AppDataLocationCheck>
{
[Test]
public void should_return_warning_when_app_data_is_child_of_startup_folder()
{
Mocker.GetMock<IAppFolderInfo>()
.Setup(s => s.StartUpFolder)
.Returns(@"C:\NzbDrone".AsOsAgnostic());
Mocker.GetMock<IAppFolderInfo>()
.Setup(s => s.AppDataFolder)
.Returns(@"C:\NzbDrone\AppData".AsOsAgnostic());
Subject.Check().ShouldBeWarning();
}
[Test]
public void should_return_warning_when_app_data_is_same_as_startup_folder()
{
Mocker.GetMock<IAppFolderInfo>()
.Setup(s => s.StartUpFolder)
.Returns(@"C:\NzbDrone".AsOsAgnostic());
Mocker.GetMock<IAppFolderInfo>()
.Setup(s => s.AppDataFolder)
.Returns(@"C:\NzbDrone".AsOsAgnostic());
Subject.Check().ShouldBeWarning();
}
[Test]
public void should_return_ok_when_no_conflict()
{
Mocker.GetMock<IAppFolderInfo>()
.Setup(s => s.StartUpFolder)
.Returns(@"C:\NzbDrone".AsOsAgnostic());
Mocker.GetMock<IAppFolderInfo>()
.Setup(s => s.AppDataFolder)
.Returns(@"C:\ProgramData\NzbDrone".AsOsAgnostic());
Subject.Check().ShouldBeOk();
}
}
}

@ -1,10 +1,9 @@
using System; using System;
using FluentAssertions;
using Moq; using Moq;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Common.Disk; using NzbDrone.Common.Disk;
using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Core.HealthCheck; using NzbDrone.Core.Configuration;
using NzbDrone.Core.HealthCheck.Checks; using NzbDrone.Core.HealthCheck.Checks;
using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Test.Framework;
@ -28,5 +27,25 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks
Subject.Check().ShouldBeError(); Subject.Check().ShouldBeError();
} }
[Test]
public void should_return_error_when_app_folder_is_write_protected_and_update_automatically_is_enabled()
{
MonoOnly();
Mocker.GetMock<IConfigFileProvider>()
.Setup(s => s.UpdateAutomatically)
.Returns(true);
Mocker.GetMock<IAppFolderInfo>()
.Setup(s => s.StartUpFolder)
.Returns(@"/opt/nzbdrone");
Mocker.GetMock<IDiskProvider>()
.Setup(s => s.WriteAllText(It.IsAny<String>(), It.IsAny<String>()))
.Throws<Exception>();
Subject.Check().ShouldBeError();
}
} }
} }

@ -126,6 +126,7 @@
<Compile Include="Framework\CoreTest.cs" /> <Compile Include="Framework\CoreTest.cs" />
<Compile Include="Framework\DbTest.cs" /> <Compile Include="Framework\DbTest.cs" />
<Compile Include="Framework\NBuilderExtensions.cs" /> <Compile Include="Framework\NBuilderExtensions.cs" />
<Compile Include="HealthCheck\Checks\AppDataLocationFixture.cs" />
<Compile Include="HealthCheck\Checks\RootFolderCheckFixture.cs" /> <Compile Include="HealthCheck\Checks\RootFolderCheckFixture.cs" />
<Compile Include="HealthCheck\Checks\DownloadClientCheckFixture.cs" /> <Compile Include="HealthCheck\Checks\DownloadClientCheckFixture.cs" />
<Compile Include="HealthCheck\Checks\ImportMechanismCheckFixture.cs" /> <Compile Include="HealthCheck\Checks\ImportMechanismCheckFixture.cs" />

@ -0,0 +1,34 @@
using NzbDrone.Common;
using NzbDrone.Common.EnvironmentInfo;
namespace NzbDrone.Core.HealthCheck.Checks
{
public class AppDataLocationCheck : HealthCheckBase
{
private readonly IAppFolderInfo _appFolderInfo;
public AppDataLocationCheck(IAppFolderInfo appFolderInfo)
{
_appFolderInfo = appFolderInfo;
}
public override HealthCheck Check()
{
if (_appFolderInfo.StartUpFolder.IsParentPath(_appFolderInfo.AppDataFolder) ||
_appFolderInfo.StartUpFolder.PathEquals(_appFolderInfo.AppDataFolder))
{
return new HealthCheck(GetType(), HealthCheckResult.Warning, "Updating will not be possible to prevent deleting AppData on Update");
}
return new HealthCheck(GetType());
}
public override bool CheckOnConfigChange
{
get
{
return false;
}
}
}
}

@ -2,6 +2,7 @@
using System.IO; using System.IO;
using NzbDrone.Common.Disk; using NzbDrone.Common.Disk;
using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Update; using NzbDrone.Core.Update;
namespace NzbDrone.Core.HealthCheck.Checks namespace NzbDrone.Core.HealthCheck.Checks
@ -11,19 +12,22 @@ namespace NzbDrone.Core.HealthCheck.Checks
private readonly IDiskProvider _diskProvider; private readonly IDiskProvider _diskProvider;
private readonly IAppFolderInfo _appFolderInfo; private readonly IAppFolderInfo _appFolderInfo;
private readonly ICheckUpdateService _checkUpdateService; private readonly ICheckUpdateService _checkUpdateService;
private readonly IConfigFileProvider _configFileProvider;
public UpdateCheck(IDiskProvider diskProvider, IAppFolderInfo appFolderInfo, ICheckUpdateService checkUpdateService) public UpdateCheck(IDiskProvider diskProvider,
IAppFolderInfo appFolderInfo,
ICheckUpdateService checkUpdateService,
IConfigFileProvider configFileProvider)
{ {
_diskProvider = diskProvider; _diskProvider = diskProvider;
_appFolderInfo = appFolderInfo; _appFolderInfo = appFolderInfo;
_checkUpdateService = checkUpdateService; _checkUpdateService = checkUpdateService;
_configFileProvider = configFileProvider;
} }
public override HealthCheck Check() public override HealthCheck Check()
{ {
//TODO: Check on mono as well if (OsInfo.IsWindows || (OsInfo.IsMono && _configFileProvider.UpdateAutomatically))
if (OsInfo.IsWindows)
{ {
try try
{ {

@ -285,6 +285,7 @@
<Compile Include="Exceptions\NzbDroneClientException.cs" /> <Compile Include="Exceptions\NzbDroneClientException.cs" />
<Compile Include="Exceptions\StatusCodeToExceptions.cs" /> <Compile Include="Exceptions\StatusCodeToExceptions.cs" />
<Compile Include="HealthCheck\CheckHealthCommand.cs" /> <Compile Include="HealthCheck\CheckHealthCommand.cs" />
<Compile Include="HealthCheck\Checks\AppDataLocationCheck.cs" />
<Compile Include="HealthCheck\Checks\DownloadClientCheck.cs" /> <Compile Include="HealthCheck\Checks\DownloadClientCheck.cs" />
<Compile Include="HealthCheck\Checks\ImportMechanismCheck.cs" /> <Compile Include="HealthCheck\Checks\ImportMechanismCheck.cs" />
<Compile Include="HealthCheck\Checks\MonoVersionCheck.cs" /> <Compile Include="HealthCheck\Checks\MonoVersionCheck.cs" />

@ -60,6 +60,8 @@ namespace NzbDrone.Core.Update
{ {
try try
{ {
EnsureAppDataSafety();
var updateSandboxFolder = _appFolderInfo.GetUpdateSandboxFolder(); var updateSandboxFolder = _appFolderInfo.GetUpdateSandboxFolder();
var packageDestination = Path.Combine(updateSandboxFolder, updatePackage.FileName); var packageDestination = Path.Combine(updateSandboxFolder, updatePackage.FileName);
@ -139,6 +141,15 @@ namespace NzbDrone.Core.Update
return String.Join(" ", processId, updateSandboxFolder.TrimEnd(Path.DirectorySeparatorChar).WrapInQuotes(), executingApplication.WrapInQuotes()); return String.Join(" ", processId, updateSandboxFolder.TrimEnd(Path.DirectorySeparatorChar).WrapInQuotes(), executingApplication.WrapInQuotes());
} }
private void EnsureAppDataSafety()
{
if (_appFolderInfo.StartUpFolder.IsParentPath(_appFolderInfo.AppDataFolder) ||
_appFolderInfo.StartUpFolder.PathEquals(_appFolderInfo.AppDataFolder))
{
throw new NotSupportedException("Update will cause AppData to be deleted, correct you configuration before proceeding");
}
}
public void Execute(ApplicationUpdateCommand message) public void Execute(ApplicationUpdateCommand message)
{ {
_logger.ProgressDebug("Checking for updates"); _logger.ProgressDebug("Checking for updates");

Loading…
Cancel
Save