adding support for running integration tests using packaged build.

This commit is contained in:
kay.one 2013-08-12 22:08:37 -07:00
parent dc1895ee48
commit eab6c3a4b5
21 changed files with 206 additions and 94 deletions

View File

@ -1,6 +1,7 @@
using System.Collections.Generic;
using NUnit.Framework;
using NzbDrone.Common;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Download;
@ -17,8 +18,7 @@ namespace NzbDrone.App.Test
[TestFixture]
public class ContainerFixture : TestBase
{
string[] args = new[]{"first","second"};
StartupArguments args = new StartupArguments("first", "second");
[Test]
public void should_be_able_to_resolve_indexers()

View File

@ -26,12 +26,19 @@ namespace NzbDrone.Common.Test
Path.IsPathRooted(Subject.AppDataFolder).Should().BeTrue("Path is not rooted");
}
[Test]
public void IsProduction_should_return_false_when_run_within_nunit()
{
RuntimeInfo.IsProduction.Should().BeFalse("Process name is " + Process.GetCurrentProcess().ProcessName);
}
[Test]
public void should_use_path_from_arg_if_provided()
{
var args = new StartupArguments("-data=\"c:\\users\\test\\\"");
Mocker.SetConstant<IStartupArguments>(args);
Subject.AppDataFolder.Should().Be("c:\\users\\test\\");
}
}
}

View File

@ -26,5 +26,17 @@ namespace NzbDrone.Common.Test.EnvironmentTests
args.Flags.Contains("t").Should().BeTrue();
}
[TestCase("/key=value")]
[TestCase("/KEY=value")]
[TestCase(" /key=\"value\"")]
public void should_parse_args_with_alues(string arg)
{
var args = new StartupArguments(new[] { arg });
args.Args.Should().HaveCount(1);
args.Args["key"].Should().Be("value");
}
}
}

View File

@ -1,6 +1,7 @@
using System.Linq;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Lifecycle;
using NzbDrone.Host;
@ -14,7 +15,7 @@ namespace NzbDrone.Common.Test
[SetUp]
public void setup()
{
Mocker.SetConstant(MainAppContainerBuilder.BuildContainer(new string[0]));
Mocker.SetConstant(MainAppContainerBuilder.BuildContainer(new StartupArguments()));
}
[Test]

View File

@ -21,7 +21,7 @@ namespace NzbDrone.Common.EnvironmentInfo
private readonly Environment.SpecialFolder DATA_SPECIAL_FOLDER = Environment.SpecialFolder.CommonApplicationData;
public AppFolderInfo(IDiskProvider diskProvider)
public AppFolderInfo(IDiskProvider diskProvider, IStartupArguments startupArguments)
{
_diskProvider = diskProvider;
@ -32,7 +32,17 @@ namespace NzbDrone.Common.EnvironmentInfo
_logger = LogManager.GetCurrentClassLogger();
AppDataFolder = Path.Combine(Environment.GetFolderPath(DATA_SPECIAL_FOLDER, Environment.SpecialFolderOption.Create), "NzbDrone");
if (startupArguments.Args.ContainsKey(StartupArguments.APPDATA))
{
AppDataFolder = startupArguments.Args[StartupArguments.APPDATA];
}
else
{
AppDataFolder = Path.Combine(Environment.GetFolderPath(DATA_SPECIAL_FOLDER, Environment.SpecialFolderOption.None), "NzbDrone");
}
_diskProvider.EnsureFolder(AppDataFolder);
StartUpFolder = new FileInfo(Assembly.GetExecutingAssembly().Location).Directory.FullName;
TempFolder = Path.GetTempPath();

View File

@ -1,26 +1,49 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
namespace NzbDrone.Common.EnvironmentInfo
{
public class StartupArguments
public interface IStartupArguments
{
HashSet<string> Flags { get; }
Dictionary<string, string> Args { get; }
}
public const string NO_BROWSER = "no-browser";
public class StartupArguments : IStartupArguments
{
public const string APPDATA = "data";
public const string NO_BROWSER = "nobrowser";
public const string INSTALL_SERVICE = "i";
public const string UNINSTALL_SERVICE = "u";
public const string HELP = "?";
public StartupArguments(string[] args)
public StartupArguments(params string[] args)
{
Flags = new HashSet<string>();
Args = new Dictionary<string, string>();
foreach (var s in args)
{
var flag = s.Trim(' ', '/', '-').ToLower();
var argParts = flag.Split('=');
if (argParts.Length == 2)
{
Args.Add(argParts[0].Trim(), argParts[1].Trim(' ', '"'));
}
else
{
Flags.Add(flag);
}
}
Instance = this;
}
public HashSet<string> Flags { get; private set; }
public Dictionary<string, string> Args { get; private set; }
public static IStartupArguments Instance { get; private set; }
}
}

View File

@ -15,8 +15,7 @@ namespace NzbDrone.Common.Instrumentation
public ApplicationLogLayoutRenderer()
{
_appData = Path.Combine(new AppFolderInfo(new DiskProvider()).GetLogFolder(), "nzbdrone.txt");
_appData = Path.Combine(new AppFolderInfo(new DiskProvider(), StartupArguments.Instance ).GetLogFolder(), "nzbdrone.txt");
}
protected override void Append(StringBuilder builder, LogEventInfo logEvent)

View File

@ -16,7 +16,7 @@ namespace NzbDrone.Common.Instrumentation
public UpdateLogLayoutRenderer()
{
_appData = Path.Combine(new AppFolderInfo(new DiskProvider()).GetUpdateLogFolder(), DateTime.Now.ToString("yy.MM.d-HH.mm") + ".txt");
_appData = Path.Combine(new AppFolderInfo(new DiskProvider(), StartupArguments.Instance).GetUpdateLogFolder(), DateTime.Now.ToString("yy.MM.d-HH.mm") + ".txt");
}

View File

@ -96,7 +96,10 @@ namespace NzbDrone.Common
logger.Info("Starting {0} {1}", path, args);
var process = Process.Start(startInfo);
var process = new Process
{
StartInfo = startInfo
};
process.OutputDataReceived += (sender, eventArgs) =>
{

View File

@ -1,4 +1,5 @@
using System;
using NzbDrone.Common.EnvironmentInfo;
namespace NzbDrone.Console
{
@ -8,7 +9,7 @@ namespace NzbDrone.Console
{
try
{
Host.Bootstrap.Start(args);
Host.Bootstrap.Start(new StartupArguments(args));
}
catch (Exception e)
{

View File

@ -65,8 +65,6 @@ namespace NzbDrone.Core.Test.Framework
public abstract class DbTest : CoreTest
{
private ITestDatabase _db;
private IDatabase _database;
protected virtual MigrationType MigrationType
{

View File

@ -17,7 +17,7 @@ namespace NzbDrone.Core.Test.MediaCoverTests
[SetUp]
public void Setup()
{
Mocker.SetConstant<IAppFolderInfo>(new AppFolderInfo(new DiskProvider()));
Mocker.SetConstant<IAppFolderInfo>(new AppFolderInfo(new DiskProvider(), Mocker.Resolve<IStartupArguments>()));
}
[Test]

View File

@ -22,13 +22,13 @@ namespace NzbDrone.Host
private readonly IHostController _hostController;
private readonly IProcessProvider _processProvider;
private readonly PriorityMonitor _priorityMonitor;
private readonly StartupArguments _startupArguments;
private readonly IStartupArguments _startupArguments;
private readonly IFirewallAdapter _firewallAdapter;
private readonly IUrlAclAdapter _urlAclAdapter;
private readonly Logger _logger;
public NzbDroneServiceFactory(IConfigFileProvider configFileProvider, IHostController hostController, IRuntimeInfo runtimeInfo,
IProcessProvider processProvider, PriorityMonitor priorityMonitor, StartupArguments startupArguments,
IProcessProvider processProvider, PriorityMonitor priorityMonitor, IStartupArguments startupArguments,
IFirewallAdapter firewallAdapter, IUrlAclAdapter urlAclAdapter, Logger logger)
{
_configFileProvider = configFileProvider;

View File

@ -3,6 +3,7 @@ using System.Diagnostics;
using System.Reflection;
using NLog;
using NzbDrone.Common.Composition;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Instrumentation;
using NzbDrone.Common.Security;
using NzbDrone.Core.Datastore;
@ -11,17 +12,16 @@ namespace NzbDrone.Host
{
public static class Bootstrap
{
private static readonly Logger Logger = LogManager.GetLogger("AppMain");
public static IContainer Start(string[] args)
public static IContainer Start(StartupArguments args)
{
var logger = LogManager.GetLogger("AppMain");
try
{
GlobalExceptionHandlers.Register();
IgnoreCertErrorPolicy.Register();
Logger.Info("Starting NzbDrone Console. Version {0}", Assembly.GetExecutingAssembly().GetName().Version);
logger.Info("Starting NzbDrone Console. Version {0}", Assembly.GetExecutingAssembly().GetName().Version);
//Check if full version .NET is installed.
try
@ -30,7 +30,7 @@ namespace NzbDrone.Host
}
catch (Exception)
{
Logger.Error("It looks like you don't have full version of .NET Framework installed. Press any key and you will be directed to the download page.");
logger.Error("It looks like you don't have full version of .NET Framework installed. Press any key and you will be directed to the download page.");
Console.Read();
try
@ -39,7 +39,7 @@ namespace NzbDrone.Host
}
catch (Exception e)
{
Logger.Warn("Oops. can't start default browser. Please visit http://www.microsoft.com/download/en/details.aspx?id=17851 to download .NET Framework 4.");
logger.Warn("Oops. can't start default browser. Please visit http://www.microsoft.com/download/en/details.aspx?id=17851 to download .NET Framework 4.");
Console.ReadLine();
}
@ -48,14 +48,19 @@ namespace NzbDrone.Host
var container = MainAppContainerBuilder.BuildContainer(args);
throw new IndexOutOfRangeException();
DbFactory.RegisterDatabase(container);
container.Resolve<Router>().Route();
return container;
}
catch (Exception e)
{
Logger.FatalException("Epic Fail " + e.Message, e);
logger.FatalException("Epic Fail " + e.Message, e);
throw;
}
}

View File

@ -11,22 +11,22 @@ namespace NzbDrone.Host
{
public class MainAppContainerBuilder : ContainerBuilderBase
{
public static IContainer BuildContainer(string[] args)
public static IContainer BuildContainer(StartupArguments args)
{
return new MainAppContainerBuilder(args).Container;
}
private MainAppContainerBuilder(string[] args)
private MainAppContainerBuilder(StartupArguments args)
: base("NzbDrone.Host", "NzbDrone.Common", "NzbDrone.Core", "NzbDrone.Api")
{
Container.Register<IStartupArguments>(args);
AutoRegisterImplementations<NzbDronePersistentConnection>();
Container.Register(typeof(IBasicRepository<RootFolder>), typeof(BasicRepository<RootFolder>));
Container.Register(typeof(IBasicRepository<NamingConfig>), typeof(BasicRepository<NamingConfig>));
Container.Register<INancyBootstrapper, NancyBootstrapper>();
Container.Register(new StartupArguments(args));
}
}
}

View File

@ -8,12 +8,12 @@ namespace NzbDrone.Host
{
private readonly INzbDroneServiceFactory _nzbDroneServiceFactory;
private readonly IServiceProvider _serviceProvider;
private readonly StartupArguments _startupArguments;
private readonly IStartupArguments _startupArguments;
private readonly IConsoleService _consoleService;
private readonly IRuntimeInfo _runtimeInfo;
private readonly Logger _logger;
public Router(INzbDroneServiceFactory nzbDroneServiceFactory, IServiceProvider serviceProvider, StartupArguments startupArguments,
public Router(INzbDroneServiceFactory nzbDroneServiceFactory, IServiceProvider serviceProvider, IStartupArguments startupArguments,
IConsoleService consoleService, IRuntimeInfo runtimeInfo, Logger logger)
{
_nzbDroneServiceFactory = nzbDroneServiceFactory;

View File

@ -19,7 +19,6 @@ namespace NzbDrone.Integration.Test.Client
return Get<List<SeriesResource>>(request);
}
public SeriesResource Get(string slug, HttpStatusCode statusCode = HttpStatusCode.OK)
{
var request = BuildRequest(slug);
@ -27,4 +26,15 @@ namespace NzbDrone.Integration.Test.Client
}
}
public class SystemInfoClient : ClientBase<SeriesResource>
{
public SystemInfoClient(IRestClient restClient)
: base(restClient)
{
}
}
}

View File

@ -1,20 +1,12 @@
using System.Collections.Generic;
using Moq;
using NLog;
using NLog.Config;
using NLog.Targets;
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Threading;
using NUnit.Framework;
using NzbDrone.Api;
using NzbDrone.Api.Commands;
using NzbDrone.Api.RootFolders;
using NzbDrone.Common.Composition;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Jobs;
using NzbDrone.Host;
using NzbDrone.Host.Owin;
using NzbDrone.Host.Owin.MiddleWare;
using NzbDrone.Integration.Test.Client;
using NzbDrone.Test.Common.Categories;
using RestSharp;
@ -25,64 +17,110 @@ namespace NzbDrone.Integration.Test
[IntegrationTest]
public abstract class IntegrationTest
{
private NancyBootstrapper _bootstrapper;
private IHostController _hostController;
protected RestClient RestClient { get; private set; }
private static readonly Logger Logger = LogManager.GetLogger("TEST");
protected IContainer Container { get; private set; }
protected SeriesClient Series;
protected ClientBase<RootFolderResource> RootFolders;
protected ClientBase<CommandResource> Commands;
protected ReleaseClient Releases;
protected IndexerClient Indexers;
private static void ResetLogger()
{
LogManager.Configuration = new LoggingConfiguration();
var consoleTarget = new ConsoleTarget { Layout = "${time} - ${logger} - ${message} ${exception}" };
LogManager.Configuration.AddTarget(consoleTarget.GetType().Name, consoleTarget);
LogManager.Configuration.LoggingRules.Add(new LoggingRule("*", LogLevel.Trace, consoleTarget));
LogManager.ReconfigExistingLoggers();
}
[SetUp]
public void SmokeTestSetup()
{
ResetLogger();
Container = MainAppContainerBuilder.BuildContainer(new string[0]);
Container.Register(typeof(IAppFolderInfo), new IntegrationTestFolderInfo());
DbFactory.RegisterDatabase(Container);
var taskManagerMock = new Mock<ITaskManager>();
taskManagerMock.Setup(c => c.GetPending()).Returns(new List<ScheduledTask>());
Container.TinyContainer.Register(taskManagerMock.Object);
_bootstrapper = new NancyBootstrapper(Container.TinyContainer);
var hostConfig = new Mock<IConfigFileProvider>();
hostConfig.SetupGet(c => c.Port).Returns(1313);
_hostController = new OwinHostController(hostConfig.Object, new[] { new NancyMiddleWare(_bootstrapper) }, Logger);
new StartupArguments();
KillNzbDrone();
InitRestClients();
_hostController.StartServer();
PackageStart();
}
private static void KillNzbDrone()
{
foreach (var p in Process.GetProcessesByName("NzbDrone.Console"))
{
try
{
p.Kill();
}
catch (Win32Exception)
{
}
}
}
private string AppDate;
private void PackageStart()
{
AppDate = Path.Combine(Directory.GetCurrentDirectory(), "_intg_" + DateTime.Now.Ticks);
Start("..\\..\\..\\..\\_output\\NzbDrone.Console.exe");
while (RestClient.Get(new RestRequest("system/status")).ResponseStatus != ResponseStatus.Completed)
{
Thread.Sleep(1000);
}
}
private Process Start(string path)
{
var args = "-nobrowser -data=\"" + AppDate + "\"";
var startInfo = new ProcessStartInfo(path, args)
{
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardError = true,
RedirectStandardOutput = true,
};
Console.WriteLine("Starting {0} {1}", path, args);
var process = new Process
{
StartInfo = startInfo
};
process.OutputDataReceived += (sender, eventArgs) =>
{
if (string.IsNullOrWhiteSpace(eventArgs.Data)) return;
if (eventArgs.Data.Contains("Press enter to exit"))
{
Assert.Fail("Process waiting for input");
}
Console.WriteLine(eventArgs.Data);
};
process.ErrorDataReceived += (sender, eventArgs) =>
{
if (string.IsNullOrWhiteSpace(eventArgs.Data)) return;
if (eventArgs.Data.Contains("Press enter to exit"))
{
Assert.Fail("Process waiting for input");
}
Console.WriteLine(eventArgs.Data);
};
process.Start();
process.BeginErrorReadLine();
process.BeginOutputReadLine();
return process;
}
private void InitRestClients()
{
RestClient = new RestClient(_hostController.AppUrl + "/api/");
RestClient = new RestClient("http://localhost:8989/api");
Series = new SeriesClient(RestClient);
Releases = new ReleaseClient(RestClient);
RootFolders = new ClientBase<RootFolderResource>(RestClient);
@ -93,8 +131,7 @@ namespace NzbDrone.Integration.Test
[TearDown]
public void SmokeTestTearDown()
{
_hostController.StopServer();
_bootstrapper.Shutdown();
KillNzbDrone();
}
}

View File

@ -2,15 +2,20 @@ using NLog;
using NLog.Config;
using NLog.Targets;
using NUnit.Framework;
using NzbDrone.Common.EnvironmentInfo;
namespace NzbDrone.Test.Common
{
public abstract class LoggingTest
{
protected Logger TestLogger = LogManager.GetLogger("TestLogger");
protected static Logger TestLogger;
protected static void InitLogging()
{
new StartupArguments();
TestLogger = LogManager.GetLogger("TestLogger");
if (LogManager.Configuration == null || LogManager.Configuration is XmlLoggingConfiguration)
{
LogManager.Configuration = new LoggingConfiguration();

View File

@ -81,7 +81,7 @@ namespace NzbDrone.Test.Common
Mocker.SetConstant(LogManager.GetLogger("TestLogger"));
Mocker.SetConstant(new StartupArguments(new string[0]));
Mocker.SetConstant<IStartupArguments>(new StartupArguments(new string[0]));
LogManager.ReconfigExistingLoggers();

View File

@ -1,5 +1,6 @@
using System;
using System.Windows.Forms;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.SysTray;
namespace NzbDrone
@ -10,7 +11,7 @@ namespace NzbDrone
{
try
{
var container = Host.Bootstrap.Start(args);
var container = Host.Bootstrap.Start(new StartupArguments(args));
container.Register<ISystemTrayApp, SystemTrayApp>();
container.Resolve<ISystemTrayApp>().Start();
}