Skip to content

Commit

Permalink
Add Nybus.Extensions.Hosting.Lambda package (#84)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kralizek committed Feb 28, 2019
1 parent 3198a4d commit b7006b2
Show file tree
Hide file tree
Showing 7 changed files with 321 additions and 4 deletions.
30 changes: 30 additions & 0 deletions Nybus.sln
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestUtils", "tests\TestUtil
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests.Nybus.Extensions.Hosting.TopShelf", "tests\Tests.Nybus.Extensions.Hosting.TopShelf\Tests.Nybus.Extensions.Hosting.TopShelf.csproj", "{0ADB6705-0DC9-4C01-ACB5-2DCB5C153789}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nybus.Extensions.Hosting.Lambda", "src\extensions\hosting\Nybus.Extensions.Hosting.Lambda\Nybus.Extensions.Hosting.Lambda.csproj", "{D970A97C-44CB-45C5-B233-8086BE9FBC18}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests.Nybus.Extensions.Hosting.Lambda", "tests\Tests.Nybus.Extensions.Hosting.Lambda\Tests.Nybus.Extensions.Hosting.Lambda.csproj", "{DF6EDE99-73F0-4B8A-B43F-3CD75E0058AE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -356,6 +360,30 @@ Global
{0ADB6705-0DC9-4C01-ACB5-2DCB5C153789}.Release|x64.Build.0 = Release|Any CPU
{0ADB6705-0DC9-4C01-ACB5-2DCB5C153789}.Release|x86.ActiveCfg = Release|Any CPU
{0ADB6705-0DC9-4C01-ACB5-2DCB5C153789}.Release|x86.Build.0 = Release|Any CPU
{D970A97C-44CB-45C5-B233-8086BE9FBC18}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D970A97C-44CB-45C5-B233-8086BE9FBC18}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D970A97C-44CB-45C5-B233-8086BE9FBC18}.Debug|x64.ActiveCfg = Debug|Any CPU
{D970A97C-44CB-45C5-B233-8086BE9FBC18}.Debug|x64.Build.0 = Debug|Any CPU
{D970A97C-44CB-45C5-B233-8086BE9FBC18}.Debug|x86.ActiveCfg = Debug|Any CPU
{D970A97C-44CB-45C5-B233-8086BE9FBC18}.Debug|x86.Build.0 = Debug|Any CPU
{D970A97C-44CB-45C5-B233-8086BE9FBC18}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D970A97C-44CB-45C5-B233-8086BE9FBC18}.Release|Any CPU.Build.0 = Release|Any CPU
{D970A97C-44CB-45C5-B233-8086BE9FBC18}.Release|x64.ActiveCfg = Release|Any CPU
{D970A97C-44CB-45C5-B233-8086BE9FBC18}.Release|x64.Build.0 = Release|Any CPU
{D970A97C-44CB-45C5-B233-8086BE9FBC18}.Release|x86.ActiveCfg = Release|Any CPU
{D970A97C-44CB-45C5-B233-8086BE9FBC18}.Release|x86.Build.0 = Release|Any CPU
{DF6EDE99-73F0-4B8A-B43F-3CD75E0058AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DF6EDE99-73F0-4B8A-B43F-3CD75E0058AE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DF6EDE99-73F0-4B8A-B43F-3CD75E0058AE}.Debug|x64.ActiveCfg = Debug|Any CPU
{DF6EDE99-73F0-4B8A-B43F-3CD75E0058AE}.Debug|x64.Build.0 = Debug|Any CPU
{DF6EDE99-73F0-4B8A-B43F-3CD75E0058AE}.Debug|x86.ActiveCfg = Debug|Any CPU
{DF6EDE99-73F0-4B8A-B43F-3CD75E0058AE}.Debug|x86.Build.0 = Debug|Any CPU
{DF6EDE99-73F0-4B8A-B43F-3CD75E0058AE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DF6EDE99-73F0-4B8A-B43F-3CD75E0058AE}.Release|Any CPU.Build.0 = Release|Any CPU
{DF6EDE99-73F0-4B8A-B43F-3CD75E0058AE}.Release|x64.ActiveCfg = Release|Any CPU
{DF6EDE99-73F0-4B8A-B43F-3CD75E0058AE}.Release|x64.Build.0 = Release|Any CPU
{DF6EDE99-73F0-4B8A-B43F-3CD75E0058AE}.Release|x86.ActiveCfg = Release|Any CPU
{DF6EDE99-73F0-4B8A-B43F-3CD75E0058AE}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{48BAF0EF-F200-4809-9ED7-E2B67CE8DD8A} = {BFE4A74D-7641-4C6B-8D39-14173BB82320}
Expand Down Expand Up @@ -387,5 +415,7 @@ Global
{25F804E9-63D1-48F2-AFB6-B9DD065A2786} = {AF1E016D-895D-48F1-8690-C49AB8F926B2}
{78F69BA5-F7F0-45AB-A268-CDFCCAF93FA1} = {AF1E016D-895D-48F1-8690-C49AB8F926B2}
{0ADB6705-0DC9-4C01-ACB5-2DCB5C153789} = {AF1E016D-895D-48F1-8690-C49AB8F926B2}
{D970A97C-44CB-45C5-B233-8086BE9FBC18} = {51A43FF2-AD6A-44CB-AE93-7FC832BFA57E}
{DF6EDE99-73F0-4B8A-B43F-3CD75E0058AE} = {AF1E016D-895D-48F1-8690-C49AB8F926B2}
EndGlobalSection
EndGlobal
20 changes: 16 additions & 4 deletions build.cake
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,17 @@ Task("RunTests")
bool success = true;
foreach (var framework in frameworks)
foreach (var file in projectFiles)
{
var frameworkFriendlyName = framework.Replace(".", "-");
var targetFrameworks = GetTargetFrameworks(file);
foreach (var file in projectFiles)
foreach (var framework in targetFrameworks)
{
var frameworkFriendlyName = framework.Replace(".", "-");
try
{
Information($"Testing {file.GetFilenameWithoutExtension()}");
Information($"Testing {file.GetFilenameWithoutExtension()} ({framework})");
var testResultFile = state.Paths.TestOutputFolder.CombineWithFilePath($"{file.GetFilenameWithoutExtension()}-{frameworkFriendlyName}.trx");
var coverageResultFile = state.Paths.TestOutputFolder.CombineWithFilePath($"{file.GetFilenameWithoutExtension()}-{frameworkFriendlyName}.dcvr");
Expand Down Expand Up @@ -125,6 +127,16 @@ Task("RunTests")
{
throw new CakeException("There was an error while executing the tests");
}
string[] GetTargetFrameworks(FilePath file)
{
XmlPeekSettings settings = new XmlPeekSettings
{
SuppressWarning = true
};
return (XmlPeek(file, "/Project/PropertyGroup/TargetFrameworks", settings) ?? XmlPeek(file, "/Project/PropertyGroup/TargetFramework", settings)).Split(";");
}
});

Task("MergeCoverageResults")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace>Nybus</RootNamespace>
<AssemblyName>Nybus.Extensions.Hosting.Lambda</AssemblyName>

<Description>Nybus hosting in AWS Lambda</Description>
<PackageTags>dotnet-standard;queue;rx;nybus;aws-lambda;lambda</PackageTags>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\Nybus.Abstractions\Nybus.Abstractions.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Kralizek.Lambda.Template" Version="3.0.0" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using System;
using System.Threading.Tasks;
using Amazon.Lambda.Core;
using Kralizek.Lambda;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

namespace Nybus
{
public abstract class NybusFunction<TInput> : Function
{
protected NybusFunction()
{
_busHost = ServiceProvider.GetRequiredService<IBusHost>();
}

private readonly IBusHost _busHost;

public async Task FunctionHandlerAsync(TInput input, ILambdaContext context)
{
try
{
await _busHost.StartAsync().ConfigureAwait(false);

using (var scope = ServiceProvider.CreateScope())
{
var handler = scope.ServiceProvider.GetService<Kralizek.Lambda.IEventHandler<TInput>>();

if (handler == null)
{
Logger.LogCritical($"No IEventHandler<{typeof(TInput).Name}> could be found.");
throw new InvalidOperationException($"No IEventHandler<{typeof(TInput).Name}> could be found.");
}

Logger.LogInformation("Invoking handler");
await handler.HandleAsync(input, context).ConfigureAwait(false);
}
}
finally
{
await _busHost.StopAsync().ConfigureAwait(false);
}
}

protected void RegisterHandler<THandler>(IServiceCollection services) where THandler : class, Kralizek.Lambda.IEventHandler<TInput>
{
services.AddTransient<Kralizek.Lambda.IEventHandler<TInput>, THandler>();
}
}
}
102 changes: 102 additions & 0 deletions tests/Tests.Nybus.Extensions.Hosting.Lambda/NybusFunctionTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
using System;
using System.Threading.Tasks;
using Amazon.Lambda.Core;
using Moq;
using NUnit.Framework;

namespace Tests
{
[TestFixture]
public class NybusFunctionTests
{
[Test, AutoMoqData]
public void TestFunction_is_set_up(TestFunction sut)
{
Assert.That(sut.BusHost, Is.Not.Null);

Assert.That(sut.Handler, Is.Not.Null);
}

[Test, AutoMoqData]
public void TestFunctionWithHandler_is_set_up(TestFunctionWithHandler sut)
{
Assert.That(sut.BusHost, Is.Not.Null);
}

[Test, AutoMoqData]
public void TestFunctionWithNoHandler_is_set_up(TestFunctionWithNoHandler sut)
{
Assert.That(sut.BusHost, Is.Not.Null);
}

[Test, AutoMoqData]
public async Task FunctionHandlerAsync_starts_bus(TestFunction sut, string payload, ILambdaContext context)
{
await sut.FunctionHandlerAsync(payload, context);

Mock.Get(sut.BusHost).Verify(p => p.StartAsync());
}

[Test, AutoMoqData]
public async Task FunctionHandlerAsync_stops_bus(TestFunction sut, string payload, ILambdaContext context)
{
await sut.FunctionHandlerAsync(payload, context);

Mock.Get(sut.BusHost).Verify(p => p.StopAsync());
}

[Test, AutoMoqData]
public async Task FunctionHandlerAsync_starts_bus(TestFunctionWithHandler sut, string payload, ILambdaContext context)
{
await sut.FunctionHandlerAsync(payload, context);

Mock.Get(sut.BusHost).Verify(p => p.StartAsync());
}

[Test, AutoMoqData]
public async Task FunctionHandlerAsync_stops_bus(TestFunctionWithHandler sut, string payload, ILambdaContext context)
{
await sut.FunctionHandlerAsync(payload, context);

Mock.Get(sut.BusHost).Verify(p => p.StopAsync());
}

[Test, AutoMoqData]
public void FunctionHandlerAsync_starts_bus(TestFunctionWithNoHandler sut, string payload, ILambdaContext context)
{
Assert.ThrowsAsync<InvalidOperationException>(() => sut.FunctionHandlerAsync(payload, context));

Mock.Get(sut.BusHost).Verify(p => p.StartAsync());
}

[Test, AutoMoqData]
public void FunctionHandlerAsync_stops_bus(TestFunctionWithNoHandler sut, string payload, ILambdaContext context)
{
Assert.ThrowsAsync<InvalidOperationException>(() => sut.FunctionHandlerAsync(payload, context));

Mock.Get(sut.BusHost).Verify(p => p.StopAsync());
}

[Test, AutoMoqData]
public async Task FunctionHandlerAsync_invokes_handler(TestFunction sut, string payload, ILambdaContext context)
{
await sut.FunctionHandlerAsync(payload, context);

Mock.Get(sut.Handler).Verify(p => p.HandleAsync(payload, context));
}

[Test, AutoMoqData]
public async Task FunctionHandlerAsync_invokes_registered_handler(TestFunctionWithHandler sut, string payload, ILambdaContext context)
{
await sut.FunctionHandlerAsync(payload, context);

Mock.Get(TestHandler.InnerHandler).Verify(p => p.HandleAsync(payload, context));
}

[Test, AutoMoqData]
public void FunctionHandlerAsync_throws_if_no_handler_is_registered(TestFunctionWithNoHandler sut, string payload, ILambdaContext context)
{
Assert.ThrowsAsync<InvalidOperationException>(() => sut.FunctionHandlerAsync(payload, context));
}
}
}
83 changes: 83 additions & 0 deletions tests/Tests.Nybus.Extensions.Hosting.Lambda/TestFunction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
using System;
using System.Threading.Tasks;
using Amazon.Lambda.Core;
using AutoFixture;
using AutoFixture.AutoMoq;
using Kralizek.Lambda;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Nybus;

namespace Tests
{
public class TestFunction : NybusFunction<string>
{
protected override void ConfigureServices(IServiceCollection services, IExecutionEnvironment executionEnvironment)
{
IFixture fixture = new Fixture();
fixture.Customize(new AutoMoqCustomization
{
GenerateDelegates = true,
ConfigureMembers = true
});

BusHost = fixture.Create<IBusHost>();
services.AddSingleton(BusHost);

Handler = fixture.Create<Kralizek.Lambda.IEventHandler<string>>();
services.AddSingleton(Handler);
}

public IBusHost BusHost { get; private set; }

public Kralizek.Lambda.IEventHandler<string> Handler { get; private set; }
}

public class TestFunctionWithHandler : NybusFunction<string>
{
protected override void ConfigureServices(IServiceCollection services, IExecutionEnvironment executionEnvironment)
{
IFixture fixture = new Fixture();
fixture.Customize(new AutoMoqCustomization
{
GenerateDelegates = true,
ConfigureMembers = true
});

BusHost = fixture.Create<IBusHost>();
services.AddSingleton(BusHost);

RegisterHandler<TestHandler>(services);
}

public IBusHost BusHost { get; private set; }
}

public class TestFunctionWithNoHandler : NybusFunction<string>
{
protected override void ConfigureServices(IServiceCollection services, IExecutionEnvironment executionEnvironment)
{
IFixture fixture = new Fixture();
fixture.Customize(new AutoMoqCustomization
{
GenerateDelegates = true,
ConfigureMembers = true
});

BusHost = fixture.Create<IBusHost>();
services.AddSingleton(BusHost);
}

public IBusHost BusHost { get; private set; }
}

public class TestHandler : Kralizek.Lambda.IEventHandler<string>
{
public Task HandleAsync(string input, ILambdaContext context)
{
return InnerHandler.HandleAsync(input, context);
}

public static Kralizek.Lambda.IEventHandler<string> InnerHandler { get; } = Mock.Of<Kralizek.Lambda.IEventHandler<string>>();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>

<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="nunit" Version="3.11.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.11.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\extensions\hosting\Nybus.Extensions.Hosting.Lambda\Nybus.Extensions.Hosting.Lambda.csproj" />
<ProjectReference Include="..\TestUtils\TestUtils.csproj" />
</ItemGroup>

</Project>

0 comments on commit b7006b2

Please sign in to comment.