Skip to content

Commit

Permalink
Add Azure.Messaging.EventGrid based tests (#24)
Browse files Browse the repository at this point in the history
* Migrate the Azure.Messaging.EventGrid tests into here from a previously uncontrolled separate solution.
* Add test Traits
  • Loading branch information
pm7y committed Mar 24, 2021
1 parent a7e5c56 commit 4dbaabd
Show file tree
Hide file tree
Showing 23 changed files with 216 additions and 33 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Xunit;

namespace AzureEventGridSimulator.Tests.AzureMessagingTests
{
public class ActualSimulatorFixture : IDisposable, IAsyncLifetime
{
private const string SimulatorFileName = "AzureEventGridSimulator";
private bool _disposed;
private string _simulatorExePath;

private Process _simulatorProcess;

public async Task InitializeAsync()
{
var simulatorDirectory = Directory.GetCurrentDirectory();
_simulatorExePath = Path.Combine(simulatorDirectory, $"{SimulatorFileName}.exe");

KillExistingSimulators();

_simulatorProcess = Process.Start(new ProcessStartInfo(_simulatorExePath)
{
WorkingDirectory = simulatorDirectory,
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true,
Environment = { new KeyValuePair<string, string>("ASPNETCORE_ENVIRONMENT", "Development") }
});

var isAlive = false;

while (!isAlive && !_simulatorProcess.StandardOutput.EndOfStream)
{
var line = await _simulatorProcess.StandardOutput.ReadLineAsync();

isAlive = line.Contains("It's Alive");
}

if (!isAlive)
{
}
}

public Task DisposeAsync()
{
Dispose();
return Task.CompletedTask;
}

public void Dispose()
{
if (!_disposed)
{
if (_simulatorProcess?.HasExited == false)
{
_simulatorProcess?.Kill(true);
_simulatorProcess?.WaitForExit();
}

_disposed = true;
GC.SuppressFinalize(this);
}
}

private void KillExistingSimulators()
{
try
{
// Kill any existing instances of the test simulator that may still be hanging around.
// Note: there shouldn't be any unless something went wrong and the test runner didn't exit cleanly.
var simulatorProcesses = Process.GetProcesses()
.Where(o => o.ProcessName == SimulatorFileName)
.Where(o => string.Equals(o.MainModule?.FileName, _simulatorExePath, StringComparison.OrdinalIgnoreCase))
.ToArray();

foreach (var process in simulatorProcesses)
{
process.Kill();
}
}
catch
{
//
}
}

~ActualSimulatorFixture()
{
Dispose();
}
}

[CollectionDefinition(nameof(ActualSimulatorFixtureCollection))]
public class ActualSimulatorFixtureCollection : ICollectionFixture<ActualSimulatorFixture>
{
// This class has no code, and is never created. Its purpose is simply
// to be the place to apply [CollectionDefinition]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
using System;
using System.Net;
using System.Threading.Tasks;
using Azure;
using Azure.Core;
using Azure.Messaging.EventGrid;
using Shouldly;
using Xunit;

namespace AzureEventGridSimulator.Tests.AzureMessagingTests
{
/// <summary>
/// Simple tests to check that we can send an event via Azure.Messaging.EventGrid library.
/// NOTE: These tests require (and automatically start) an actual instance of AzureEventGridSimulator.exe as there is no way to inject an HttpClient (from a WebApplicationFactory)
/// into Azure.Messaging.EventGrid.
/// </summary>
[Collection(nameof(ActualSimulatorFixtureCollection))]
[Trait("Category","integration-actual")]
public class AzureMessagingEventGridTest
{
private readonly ActualSimulatorFixture _actualSimulatorFixture;

public AzureMessagingEventGridTest(ActualSimulatorFixture actualSimulatorFixture)
{
_actualSimulatorFixture = actualSimulatorFixture;
}

[Fact]
public async Task GivenValidEvent_WhenUriContainsNonStandardPort_ThenItShouldBeAccepted()
{
var client = new EventGridPublisherClient(
new Uri("https://localhost:60101/api/events"),
new AzureKeyCredential("TheLocal+DevelopmentKey="));

var response = await client.SendEventAsync(new EventGridEvent("/the/subject", "The.Event.Type", "v1", new { Id = 1, Foo = "Bar" }));

response.Status.ShouldBe((int)HttpStatusCode.OK);
}

[Fact]
public async Task GivenValidEvents_WhenUriContainsNonStandardPort_TheyShouldBeAccepted()
{
var client = new EventGridPublisherClient(
new Uri("https://localhost:60101/api/events"),
new AzureKeyCredential("TheLocal+DevelopmentKey="));

var events = new[]
{
new EventGridEvent("/the/subject1", "The.Event.Type1", "v1", new { Id = 1, Foo = "Bar" }),
new EventGridEvent("/the/subject2", "The.Event.Type2", "v1", new { Id = 2, Foo = "Baz" })
};

var response = await client.SendEventsAsync(events);

response.Status.ShouldBe((int)HttpStatusCode.OK);
}

[Fact]
public async Task GivenValidEvent_WhenUriContainsNonExistentPort_ThenItShouldNotBeAccepted()
{
var client = new EventGridPublisherClient(
new Uri("https://localhost:19999/api/events"),
new AzureKeyCredential("TheLocal+DevelopmentKey="),
new EventGridPublisherClientOptions
{ Retry = { Mode = RetryMode.Fixed, MaxRetries = 0, NetworkTimeout = TimeSpan.FromSeconds(5) } });

var exception = await Should.ThrowAsync<RequestFailedException>(async () =>
{
await client.SendEventAsync(new EventGridEvent("/the/subject", "The.Event.Type", "v1",
new { Id = 1, Foo = "Bar" }));
});

exception.Message.ShouldContain("actively refused");
exception.Status.ShouldBe(0);
}

[Fact]
public async Task GivenValidEvent_WhenKeyIsWrong_ThenItShouldNotBeAccepted()
{
var client = new EventGridPublisherClient(
new Uri("https://localhost:60101/api/events"),
new AzureKeyCredential("TheWrongLocal+DevelopmentKey="));

var exception = await Should.ThrowAsync<RequestFailedException>(async () =>
{
await client.SendEventAsync(new EventGridEvent("/the/subject", "The.Event.Type", "v1",
new { Id = 1, Foo = "Bar" }));
});

exception.Status.ShouldBe((int)HttpStatusCode.Unauthorized);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,20 @@
using Shouldly;
using Xunit;

namespace AzureEventGridSimulator.Tests.Integration
namespace AzureEventGridSimulator.Tests.IntegrationTests
{
/// <summary>
/// These test use a WebApplicationFactory based instance of the simulator
/// and an HttpClient to send send events to the simulator.
/// Note: this is a WIP.
/// </summary>
[Trait("Category","integration")]
public class BasicTests
: IClassFixture<TestContextFixture>
: IClassFixture<IntegrationContextFixture>
{
private readonly TestContextFixture _factory;
private readonly IntegrationContextFixture _factory;

public BasicTests(TestContextFixture factory)
public BasicTests(IntegrationContextFixture factory)
{
_factory = factory;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@
using Microsoft.Extensions.Logging;
using Xunit;

namespace AzureEventGridSimulator.Tests.Integration
namespace AzureEventGridSimulator.Tests.IntegrationTests
{
// ReSharper disable once ClassNeverInstantiated.Global
public class TestContextFixture : WebApplicationFactory<Startup>, IAsyncLifetime
public class IntegrationContextFixture : WebApplicationFactory<Startup>, IAsyncLifetime
{
public Task InitializeAsync()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

namespace AzureEventGridSimulator.Tests.Unit
{
[Trait("Category","unit")]
public class ConfigurationLoadingTests
{
[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

namespace AzureEventGridSimulator.Tests.Unit.Filtering
{
[Trait("Category","unit")]
public class AdvancedFilterEventAcceptanceTests
{
private static readonly EventGridEvent _gridEvent = new()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

namespace AzureEventGridSimulator.Tests.Unit.Filtering
{
[Trait("Category","unit")]
public class AdvancedFilterValidationTests
{
private static SimulatorSettings GetValidSimulatorSettings(AdvancedFilterSetting advancedFilter)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

namespace AzureEventGridSimulator.Tests.Unit.Filtering
{
[Trait("Category","unit")]
public class FilterSettingsValidationTests
{
private static SimulatorSettings GetValidSimulatorSettings(FilterSetting filter)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
using System.Linq;
using AzureEventGridSimulator.Infrastructure.Settings;

// ReSharper disable StringLiteralTypo

namespace AzureEventGridSimulator.Tests.Unit.Filtering
{
internal class NegativeFilterTestCaseContainer : IEnumerable<object[]>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
using System.Linq;
using AzureEventGridSimulator.Infrastructure.Settings;

// ReSharper disable StringLiteralTypo

namespace AzureEventGridSimulator.Tests.Unit.Filtering
{
internal class PositiveFilterTestCaseContainer : IEnumerable<object[]>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

namespace AzureEventGridSimulator.Tests.Unit.Filtering
{
[Trait("Category","unit")]
public class SimpleFilterEventAcceptanceTests
{
[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@

namespace AzureEventGridSimulator.Domain.Commands
{
// ReSharper disable once UnusedMember.Global
// ReSharper disable once UnusedType.Global
public class SendNotificationEventsToSubscriberCommandHandler : AsyncRequestHandler<SendNotificationEventsToSubscriberCommand>
{
private readonly IHttpClientFactory _httpClientFactory;
Expand Down Expand Up @@ -99,7 +97,6 @@ private async Task SendToSubscriber(SubscriptionSettings subscription, IEnumerab
{
if (subscription.Filter.AcceptsEvent(evt))
{
// ReSharper disable once MethodHasAsyncOverload
var json = JsonConvert.SerializeObject(new[] { evt }, Formatting.Indented);
using var content = new StringContent(json, Encoding.UTF8, "application/json");
var httpClient = _httpClientFactory.CreateClient();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

namespace AzureEventGridSimulator.Domain.Commands
{
// ReSharper disable once UnusedType.Global
public class ValidateAllSubscriptionsCommandHandler : IRequestHandler<ValidateAllSubscriptionsCommand>
{
private readonly IHttpClientFactory _httpClientFactory;
Expand Down Expand Up @@ -71,7 +70,6 @@ private async Task ValidateSubscription(TopicSettings topic, SubscriptionSetting
}
};

// ReSharper disable once MethodHasAsyncOverload
var json = JsonConvert.SerializeObject(new[] { evt }, Formatting.Indented);
using var content = new StringContent(json, Encoding.UTF8, "application/json");
using var httpClient = _httpClientFactory.CreateClient();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

namespace AzureEventGridSimulator.Domain.Commands
{
// ReSharper disable once UnusedType.Global
public class ValidateSubscriptionCommandHandler : IRequestHandler<ValidateSubscriptionCommand, bool>
{
private readonly ILogger<ValidateSubscriptionCommandHandler> _logger;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public static async Task WriteErrorResponse(this HttpContext context, HttpStatus
context.Response.Headers.Add(HeaderNames.ContentType, "application/json");

context.Response.StatusCode = (int)statusCode;
// ReSharper disable once MethodHasAsyncOverload

await context.Response.WriteAsync(JsonConvert.SerializeObject(error, Formatting.Indented));
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using AzureEventGridSimulator.Domain.Entities;
using AzureEventGridSimulator.Infrastructure.Settings;
Expand Down Expand Up @@ -144,7 +143,6 @@ private static bool Try(Func<bool> function, bool valueOnException = false)
}
}

[SuppressMessage("ReSharper", "InvertIf")]
private static bool TryGetValue(this EventGridEvent gridEvent, string key, out object value)
{
var retval = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

namespace AzureEventGridSimulator.Infrastructure.Middleware
{
// ReSharper disable once ClassNeverInstantiated.Global
public class EventGridMiddleware
{
private readonly RequestDelegate _next;
Expand All @@ -21,7 +20,6 @@ public EventGridMiddleware(RequestDelegate next)
_next = next;
}

// ReSharper disable once UnusedMember.Global
public async Task InvokeAsync(HttpContext context,
SimulatorSettings simulatorSettings,
SasKeyValidator sasHeaderValidator,
Expand Down Expand Up @@ -95,7 +93,6 @@ private async Task ValidateNotificationRequest(HttpContext context,

foreach (var evt in events)
{
// ReSharper disable once MethodHasAsyncOverload
var eventSize = JsonConvert.SerializeObject(evt, Formatting.None).Length;

logger.LogTrace("Event is {Bytes} in length", eventSize);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

namespace AzureEventGridSimulator.Infrastructure.Middleware
{
// ReSharper disable once ClassNeverInstantiated.Global
public class RequestLoggingMiddleware
{
private readonly RequestDelegate _next;
Expand All @@ -20,7 +19,6 @@ public RequestLoggingMiddleware(RequestDelegate next)
_next = next;
}

// ReSharper disable once UnusedMember.Global
public async Task InvokeAsync(HttpContext context,
ILogger<RequestLoggingMiddleware> logger)
{
Expand Down
Loading

0 comments on commit 4dbaabd

Please sign in to comment.