cleaned up integration test project.

This commit is contained in:
kay.one 2013-04-18 21:46:18 -07:00
parent d50f23da1c
commit 9cabe7cf90
16 changed files with 270 additions and 161 deletions

View File

@ -13,12 +13,12 @@ using TinyIoC;
namespace NzbDrone.Api
{
public class TinyNancyBootstrapper : TinyIoCNancyBootstrapper
public class NancyBootstrapper : TinyIoCNancyBootstrapper
{
private readonly TinyIoCContainer _tinyIoCContainer;
private readonly Logger _logger;
public TinyNancyBootstrapper(TinyIoCContainer tinyIoCContainer)
public NancyBootstrapper(TinyIoCContainer tinyIoCContainer)
{
_tinyIoCContainer = tinyIoCContainer;
_logger = LogManager.GetCurrentClassLogger();
@ -70,5 +70,10 @@ namespace NzbDrone.Api
var processors = ApplicationContainer.Resolve<IProcessStaticResource>();
Conventions.StaticContentsConventions.Add(processors.ProcessStaticResourceRequest);
}
public void Shutdown()
{
ApplicationContainer.Resolve<IEventAggregator>().Publish(new ApplicationShutdownRequested());
}
}
}

View File

@ -6,6 +6,8 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using NLog;
using NzbDrone.Common.Eventing;
using NzbDrone.Core.Lifecycle;
using NzbDrone.Core.Model.Notification;
using NzbDrone.Core.Providers;
@ -20,7 +22,7 @@ namespace NzbDrone.Core.Jobs
bool Enqueue(string jobTypeString);
}
public class JobController : IJobController
public class JobController : IJobController, IHandle<ApplicationShutdownRequested>
{
private readonly NotificationProvider _notificationProvider;
private readonly IEnumerable<IJob> _jobs;
@ -177,5 +179,10 @@ namespace NzbDrone.Core.Jobs
_jobRepository.Update(jobDefinition);
}
}
public void Handle(ApplicationShutdownRequested message)
{
_cancellationTokenSource.Cancel();
}
}
}

View File

@ -4,7 +4,9 @@ using NzbDrone.Core.Lifecycle;
namespace NzbDrone.Core.Jobs
{
public class JobTimer : IHandle<ApplicationStartedEvent>
public class JobTimer :
IHandle<ApplicationStartedEvent>,
IHandle<ApplicationShutdownRequested>
{
private readonly IJobController _jobController;
private readonly Timer _timer;
@ -22,5 +24,10 @@ namespace NzbDrone.Core.Jobs
_timer.Elapsed += (o, args) => _jobController.EnqueueScheduled();
_timer.Start();
}
public void Handle(ApplicationShutdownRequested message)
{
_timer.Stop();
}
}
}

View File

@ -0,0 +1,9 @@
using NzbDrone.Common.Eventing;
namespace NzbDrone.Core.Lifecycle
{
public class ApplicationShutdownRequested : IEvent
{
}
}

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -235,6 +235,7 @@
<Compile Include="Indexers\IIndexerBase.cs" />
<Compile Include="Indexers\IndexerSettingUpdatedEvent.cs" />
<Compile Include="Indexers\IndexerWithSetting.cs" />
<Compile Include="Lifecycle\ApplicationShutdownRequested.cs" />
<Compile Include="MediaFiles\Events\EpisodeDownloadedEvent.cs" />
<Compile Include="Download\EpisodeGrabbedEvent.cs" />
<Compile Include="Download\SeriesRenamedEvent.cs" />

View File

@ -0,0 +1,78 @@
using System.Collections.Generic;
using System.Net;
using FluentAssertions;
using NLog;
using RestSharp;
namespace NzbDrone.Integration.Test.Client
{
public abstract class ClientBase<TResource> where TResource : new()
{
private readonly IRestClient _restClient;
private readonly string _resource;
private readonly Logger _logger;
protected ClientBase(IRestClient restClient, string resource)
{
_restClient = restClient;
_resource = resource;
_logger = LogManager.GetLogger("REST");
}
public List<TResource> GetAll()
{
var request = BuildRequest();
return Get<List<TResource>>(request);
}
public TResource Post(TResource body)
{
var request = BuildRequest();
request.AddBody(body);
return Post<TResource>(request);
}
protected RestRequest BuildRequest(string command = "")
{
return new RestRequest(_resource + "/" + command.Trim('/'))
{
RequestFormat = DataFormat.Json
};
}
protected T Get<T>(IRestRequest request, HttpStatusCode statusCode = HttpStatusCode.OK) where T : new()
{
request.Method = Method.GET;
return Execute<T>(request, statusCode);
}
public T Post<T>(IRestRequest request, HttpStatusCode statusCode = HttpStatusCode.Created) where T : new()
{
request.Method = Method.POST;
return Execute<T>(request, statusCode);
}
private T Execute<T>(IRestRequest request, HttpStatusCode statusCode) where T : new()
{
_logger.Info("{0}: {1}", request.Method, _restClient.BuildUri(request));
var response = _restClient.Execute<T>(request);
_logger.Info("Response: {0}", response.Content);
if (response.ErrorException != null)
{
throw response.ErrorException;
}
response.ErrorMessage.Should().BeBlank();
response.StatusCode.Should().Be(statusCode);
return response.Data;
}
}
}

View File

@ -0,0 +1,22 @@
using System.Collections.Generic;
using NzbDrone.Api.Series;
using RestSharp;
namespace NzbDrone.Integration.Test.Client
{
public class SeriesClient : ClientBase<SeriesResource>
{
public SeriesClient(IRestClient restClient)
: base(restClient, "series")
{
}
public List<SeriesResource> Lookup(string term)
{
var request = BuildRequest("lookup?term={term}");
request.AddUrlSegment("term", term);
return Get<List<SeriesResource>>(request);
}
}
}

View File

@ -7,8 +7,8 @@
<ProjectGuid>{8CEFECD0-A6C2-498F-98B1-3FBE5820F9AB}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>NzbDrone.Smoke.Test</RootNamespace>
<AssemblyName>NzbDrone.Smoke.Test</AssemblyName>
<RootNamespace>NzbDrone.Integration.Test</RootNamespace>
<AssemblyName>NzbDrone.Integration.Test</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
@ -66,9 +66,11 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Client\ClientBase.cs" />
<Compile Include="Client\SeriesClient.cs" />
<Compile Include="SmokeTestBase.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SmokeTest.cs" />
<Compile Include="SeriesTest.cs" />
</ItemGroup>
<ItemGroup>
<None Include="..\NzbDrone.Test.Common\App.config">

View File

@ -0,0 +1,33 @@
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Api.Series;
namespace NzbDrone.Integration.Test
{
[TestFixture]
public class SeriesTest : SmokeTestBase
{
[Test]
public void should_have_no_series_on_start_application()
{
Series.GetAll().Should().BeEmpty();
}
[Test]
public void series_lookup_on_trakt()
{
var series = Series.Lookup("archer");
series.Should().NotBeEmpty();
series.Should().Contain(c => c.Title == "Archer (2009)");
}
[Test]
[Ignore]
public void add_series_without_required_fields_should_return_400()
{
Series.Post(new SeriesResource());
}
}
}

View File

@ -0,0 +1,96 @@
using System;
using System.IO;
using NLog;
using NLog.Config;
using NLog.Targets;
using NUnit.Framework;
using Nancy.Hosting.Self;
using NzbDrone.Api;
using NzbDrone.Common;
using NzbDrone.Core.Datastore;
using NzbDrone.Integration.Test.Client;
using RestSharp;
using TinyIoC;
namespace NzbDrone.Integration.Test
{
[TestFixture]
public abstract class SmokeTestBase
{
private NancyBootstrapper _bootstrapper;
private NancyHost _host;
protected RestClient RestClient { get; private set; }
private static readonly Logger Logger = LogManager.GetLogger("TEST");
protected TinyIoCContainer Container { get; private set; }
protected SeriesClient Series;
static SmokeTestBase()
{
if (LogManager.Configuration == null || LogManager.Configuration is XmlLoggingConfiguration)
{
LogManager.Configuration = new LoggingConfiguration();
var consoleTarget = new ConsoleTarget { Layout = "${logger} - ${message} ${exception}" };
LogManager.Configuration.AddTarget(consoleTarget.GetType().Name, consoleTarget);
LogManager.Configuration.LoggingRules.Add(new LoggingRule("*", LogLevel.Debug, consoleTarget));
}
LogManager.ReconfigExistingLoggers();
}
private void InitDatabase()
{
Logger.Info("Registering Database...");
//TODO: move this to factory
var environmentProvider = new EnvironmentProvider();
var appDataPath = environmentProvider.GetAppDataPath();
if (!Directory.Exists(appDataPath))
{
Directory.CreateDirectory(appDataPath);
}
var dbPath = Path.Combine(environmentProvider.WorkingDirectory, DateTime.Now.Ticks + ".db");
Logger.Info("Working Folder: {0}", environmentProvider.WorkingDirectory);
Logger.Info("Data Folder: {0}", environmentProvider.GetAppDataPath());
Logger.Info("DB Na: {0}", dbPath);
Container.Register((c, p) => c.Resolve<IDbFactory>().Create(dbPath));
}
[SetUp]
public void SmokeTestSetup()
{
Container = ContainerBuilder.BuildNzbDroneContainer();
InitDatabase();
_bootstrapper = new NancyBootstrapper(Container);
const string url = "http://localhost:1313";
_host = new NancyHost(new Uri(url), _bootstrapper);
RestClient = new RestClient(url + "/api/");
Series = new SeriesClient(RestClient);
_host.Start();
}
[TearDown]
public void SmokeTestTearDown()
{
_host.Stop();
_bootstrapper.Shutdown();
}
}
}

View File

@ -1,27 +0,0 @@
using System.Collections.Generic;
using NUnit.Framework;
using NzbDrone.Api.Series;
using RestSharp;
namespace NzbDrone.Smoke.Test
{
[TestFixture]
public class SmokeTest : SmokeTestBase
{
[Test]
public void start_application()
{
Get<List<SeriesResource>>(new RestRequest("series"));
}
[Test]
[Ignore]
public void add_series_without_required_fields_should_return_400()
{
var addSeriesRequest = new RestRequest("series") { RequestFormat = DataFormat.Json };
addSeriesRequest.AddBody(new SeriesResource());
Post<SeriesResource>(addSeriesRequest);
}
}
}

View File

@ -1,124 +0,0 @@
using System;
using System.IO;
using System.Net;
using FluentAssertions;
using NLog;
using NLog.Config;
using NLog.Targets;
using NUnit.Framework;
using Nancy.Hosting.Self;
using NzbDrone.Api;
using NzbDrone.Common;
using RestSharp;
using TinyIoC;
namespace NzbDrone.Smoke.Test
{
[TestFixture]
public abstract class SmokeTestBase
{
private TinyNancyBootstrapper _bootstrapper;
private NancyHost _host;
protected RestClient RestClient { get; private set; }
private static readonly Logger RestLogger = LogManager.GetLogger("REST: ");
private static readonly Logger Logger = LogManager.GetLogger("TEST: ");
private EnvironmentProvider _environmentProvider;
protected TinyIoCContainer Container { get; private set; }
static SmokeTestBase()
{
if (LogManager.Configuration == null || LogManager.Configuration is XmlLoggingConfiguration)
{
LogManager.Configuration = new LoggingConfiguration();
var consoleTarget = new ConsoleTarget { Layout = "${message} ${exception}" };
LogManager.Configuration.AddTarget(consoleTarget.GetType().Name, consoleTarget);
LogManager.Configuration.LoggingRules.Add(new LoggingRule("*", LogLevel.Debug, consoleTarget));
}
LogManager.ReconfigExistingLoggers();
}
[SetUp]
public void SmokeTestSetup()
{
_environmentProvider = new EnvironmentProvider();
if (Directory.Exists(_environmentProvider.GetAppDataPath()))
{
Directory.Delete(_environmentProvider.GetAppDataPath(), true);
}
Logger.Info("Working Folder: {0}", _environmentProvider.WorkingDirectory);
Logger.Info("Data Folder: {0}", _environmentProvider.GetAppDataPath());
Logger.Info("DB Path: {0}", _environmentProvider.GetNzbDroneDatabase());
Container = ContainerBuilder.BuildNzbDroneContainer();
_bootstrapper = new TinyNancyBootstrapper(Container);
const string url = "http://localhost:1313";
_host = new NancyHost(new Uri(url), _bootstrapper);
RestClient = new RestClient(url + "/api/");
_host.Start();
}
[TearDown]
public void SmokeTestTearDown()
{
_host.Stop();
}
protected T Get<T>(IRestRequest request, HttpStatusCode statusCode = HttpStatusCode.OK) where T : class,new()
{
RestLogger.Info("GET: {0}", RestClient.BuildUri(request));
var response = RestClient.Get<T>(request);
RestLogger.Info("Response: {0}", response.Content);
if (response.ErrorException != null)
{
throw response.ErrorException;
}
response.ErrorMessage.Should().BeBlank();
response.StatusCode.Should().Be(statusCode);
return response.Data;
}
protected T Post<T>(IRestRequest request, HttpStatusCode statusCode = HttpStatusCode.Created) where T : class,new()
{
RestLogger.Info("POST: {0}", RestClient.BuildUri(request));
var response = RestClient.Post<T>(request);
RestLogger.Info("Response: {0}", response.Content);
if (response.ErrorException != null)
{
throw response.ErrorException;
}
response.ErrorMessage.Should().BeBlank();
response.StatusCode.Should().Be(statusCode);
return response.Data;
}
}
}

View File

@ -48,7 +48,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Marr.Data", "Marr.Data\Marr
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NzbDrone.Libraries.Test", "NzbDrone.Libraries.Test\NzbDrone.Libraries.Test.csproj", "{CBF6B8B0-A015-413A-8C86-01238BB45770}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NzbDrone.Smoke.Test", "NzbDrone.Smoke.Test\NzbDrone.Smoke.Test.csproj", "{8CEFECD0-A6C2-498F-98B1-3FBE5820F9AB}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NzbDrone.Integration.Test", "NzbDrone.Integration.Test\NzbDrone.Integration.Test.csproj", "{8CEFECD0-A6C2-498F-98B1-3FBE5820F9AB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution

View File

@ -41,7 +41,7 @@ namespace NzbDrone
container.AutoRegisterImplementations<ExternalNotificationBase>();
container.Register<IEventAggregator, EventAggregator>().AsSingleton();
container.Register<INancyBootstrapper, TinyNancyBootstrapper>().AsSingleton();
container.Register<INancyBootstrapper, NancyBootstrapper>().AsSingleton();
container.Register<IAnnouncer, MigrationLogger>().AsSingleton();
container.Register<Router>().AsSingleton();