From 1f28ad8ec2d3b2f65dbe30eaefa3d8b3d84d2a67 Mon Sep 17 00:00:00 2001 From: Artem Derevnjuk Date: Tue, 3 Oct 2023 18:54:14 +0400 Subject: [PATCH] feat(repeater): refrain from utilizing non standard ports closes #165 --- .../Bus/DefaultRepeaterBusFactory.cs | 51 +++++ .../Bus/DefaultRepeaterEventBusFactory.cs | 38 ---- src/SecTester.Repeater/Bus/IRepeaterBus.cs | 15 ++ .../Bus/IRepeaterBusFactory.cs | 6 + .../Bus/IRepeaterEventBusFactory.cs | 8 - ...stExecutingEvent.cs => IncomingRequest.cs} | 7 +- ...ExecutingResult.cs => OutgoingResponse.cs} | 7 +- .../Bus/RegisterRepeaterCommand.cs | 6 - .../Bus/RegisterRepeaterPayload.cs | 3 - .../Bus/RegisterRepeaterResult.cs | 3 - .../Bus/RepeaterRegisteringError.cs | 10 - .../Bus/RepeaterStatusEvent.cs | 6 - .../Bus/RequestExecutingEventListener.cs | 30 --- .../Bus/SocketIoRepeaterBus.cs | 136 +++++++++++ .../DefaultRepeaterFactory.cs | 18 +- .../Extensions/ServiceCollectionExtensions.cs | 3 +- src/SecTester.Repeater/Repeater.cs | 112 ++++----- .../Runners/HttpRequestRunner.cs | 6 +- src/SecTester.Repeater/Runtime.cs | 12 + .../SecTester.Repeater.csproj | 2 + src/SecTester.Repeater/packages.lock.json | 137 ++++++++++- src/SecTester.Reporter/packages.lock.json | 6 +- src/SecTester.Runner/packages.lock.json | 149 ++++++++++-- src/SecTester.Scan/packages.lock.json | 2 +- test/SecTester.Bus.Tests/packages.lock.json | 6 +- .../Bus/DefaultRepeaterBusFactoryTests.cs | 49 ++++ .../DefaultRepeaterEventBusFactoryTests.cs | 53 ----- .../Bus/RequestExecutingEventHandlerTests.cs | 58 ----- .../DefaultRepeaterFactoryTests.cs | 9 +- .../SecTester.Repeater.Tests/RepeaterTests.cs | 214 ++++++++---------- .../Runners/HttpRequestRunnerTests.cs | 26 +-- .../packages.lock.json | 89 +++++++- .../packages.lock.json | 8 +- .../SecTester.Runner.Tests/packages.lock.json | 103 +++++++-- test/SecTester.Scan.Tests/packages.lock.json | 6 +- 35 files changed, 882 insertions(+), 512 deletions(-) create mode 100644 src/SecTester.Repeater/Bus/DefaultRepeaterBusFactory.cs delete mode 100644 src/SecTester.Repeater/Bus/DefaultRepeaterEventBusFactory.cs create mode 100644 src/SecTester.Repeater/Bus/IRepeaterBus.cs create mode 100644 src/SecTester.Repeater/Bus/IRepeaterBusFactory.cs delete mode 100644 src/SecTester.Repeater/Bus/IRepeaterEventBusFactory.cs rename src/SecTester.Repeater/Bus/{RequestExecutingEvent.cs => IncomingRequest.cs} (67%) rename src/SecTester.Repeater/Bus/{RequestExecutingResult.cs => OutgoingResponse.cs} (62%) delete mode 100644 src/SecTester.Repeater/Bus/RegisterRepeaterCommand.cs delete mode 100644 src/SecTester.Repeater/Bus/RegisterRepeaterPayload.cs delete mode 100644 src/SecTester.Repeater/Bus/RegisterRepeaterResult.cs delete mode 100644 src/SecTester.Repeater/Bus/RepeaterRegisteringError.cs delete mode 100644 src/SecTester.Repeater/Bus/RepeaterStatusEvent.cs delete mode 100644 src/SecTester.Repeater/Bus/RequestExecutingEventListener.cs create mode 100644 src/SecTester.Repeater/Bus/SocketIoRepeaterBus.cs create mode 100644 src/SecTester.Repeater/Runtime.cs create mode 100644 test/SecTester.Repeater.Tests/Bus/DefaultRepeaterBusFactoryTests.cs delete mode 100644 test/SecTester.Repeater.Tests/Bus/DefaultRepeaterEventBusFactoryTests.cs delete mode 100644 test/SecTester.Repeater.Tests/Bus/RequestExecutingEventHandlerTests.cs diff --git a/src/SecTester.Repeater/Bus/DefaultRepeaterBusFactory.cs b/src/SecTester.Repeater/Bus/DefaultRepeaterBusFactory.cs new file mode 100644 index 0000000..d9cda1f --- /dev/null +++ b/src/SecTester.Repeater/Bus/DefaultRepeaterBusFactory.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using Microsoft.Extensions.Logging; +using SecTester.Core; +using SecTester.Core.Utils; +using SocketIO.Serializer.MessagePack; +using SocketIOClient; + +namespace SecTester.Repeater.Bus; + +public class DefaultRepeaterBusFactory : IRepeaterBusFactory +{ + private readonly Configuration _config; + private readonly ITimerProvider _timerProvider; + private readonly ILoggerFactory _loggerFactory; + + public DefaultRepeaterBusFactory(Configuration config, ITimerProvider timerProvider, ILoggerFactory loggerFactory) + { + _config = config ?? throw new ArgumentNullException(nameof(config)); + _timerProvider = timerProvider ?? throw new ArgumentNullException(nameof(timerProvider)); + _loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory)); + } + + public IRepeaterBus Create(string repeaterId) + { + if (_config.Credentials is null) + { + throw new InvalidOperationException( + "Please provide credentials to establish a connection with the bus." + ); + } + + var url = new Uri(_config.Api); + var client = new SocketIOClient.SocketIO(url, new SocketIOOptions + { + Path = "/api/ws/v1", + ReconnectionAttempts = 20, + ReconnectionDelayMax = 86400000, + ConnectionTimeout = TimeSpan.FromSeconds(10), + Auth = new List> + { + new("token", _config.Credentials!.Token), new("domain", repeaterId) + }, + }) + { + Serializer = new SocketIOMessagePackSerializer() + }; + + return new SocketIoRepeaterBus(url, client, _timerProvider, _loggerFactory.CreateLogger()); + } +} diff --git a/src/SecTester.Repeater/Bus/DefaultRepeaterEventBusFactory.cs b/src/SecTester.Repeater/Bus/DefaultRepeaterEventBusFactory.cs deleted file mode 100644 index 2987777..0000000 --- a/src/SecTester.Repeater/Bus/DefaultRepeaterEventBusFactory.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -using SecTester.Bus.Dispatchers; -using SecTester.Core; -using SecTester.Core.Bus; - -namespace SecTester.Repeater.Bus; - -public class DefaultRepeaterEventBusFactory : IRepeaterEventBusFactory -{ - private readonly Configuration _config; - private readonly IRmqEventBusFactory _rmqEventBusFactory; - - public DefaultRepeaterEventBusFactory(Configuration config, IRmqEventBusFactory rmqEventBusFactory) - { - _config = config ?? throw new ArgumentNullException(nameof(config)); - _rmqEventBusFactory = rmqEventBusFactory ?? throw new ArgumentNullException(nameof(rmqEventBusFactory)); - } - - public IEventBus Create(string repeaterId) - { - if (_config.Credentials == null) - { - throw new InvalidOperationException( - "Please provide credentials to establish a connection with the bus." - ); - } - - var options = new RmqEventBusOptions(_config.Bus, "app", "EventBus", $"agent:{repeaterId}") - { - Username = "bot", - Password = _config.Credentials!.Token, - HeartbeatInterval = TimeSpan.FromSeconds(30), - ConnectTimeout = TimeSpan.FromSeconds(30) - }; - - return _rmqEventBusFactory.CreateEventBus(options); - } -} diff --git a/src/SecTester.Repeater/Bus/IRepeaterBus.cs b/src/SecTester.Repeater/Bus/IRepeaterBus.cs new file mode 100644 index 0000000..5948db1 --- /dev/null +++ b/src/SecTester.Repeater/Bus/IRepeaterBus.cs @@ -0,0 +1,15 @@ +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace SecTester.Repeater.Bus; + +public interface IRepeaterBus : IAsyncDisposable +{ + event Func> RequestReceived; + event Action ErrorOccurred; + event Action UpgradeAvailable; + + Task Connect(); + Task Deploy(string repeaterId, Runtime? runtime = null, CancellationToken? cancellationToken = null); +} diff --git a/src/SecTester.Repeater/Bus/IRepeaterBusFactory.cs b/src/SecTester.Repeater/Bus/IRepeaterBusFactory.cs new file mode 100644 index 0000000..505fa63 --- /dev/null +++ b/src/SecTester.Repeater/Bus/IRepeaterBusFactory.cs @@ -0,0 +1,6 @@ +namespace SecTester.Repeater.Bus; + +public interface IRepeaterBusFactory +{ + IRepeaterBus Create(string repeaterId); +} diff --git a/src/SecTester.Repeater/Bus/IRepeaterEventBusFactory.cs b/src/SecTester.Repeater/Bus/IRepeaterEventBusFactory.cs deleted file mode 100644 index 83226e2..0000000 --- a/src/SecTester.Repeater/Bus/IRepeaterEventBusFactory.cs +++ /dev/null @@ -1,8 +0,0 @@ -using SecTester.Core.Bus; - -namespace SecTester.Repeater.Bus; - -public interface IRepeaterEventBusFactory -{ - IEventBus Create(string repeaterId); -} diff --git a/src/SecTester.Repeater/Bus/RequestExecutingEvent.cs b/src/SecTester.Repeater/Bus/IncomingRequest.cs similarity index 67% rename from src/SecTester.Repeater/Bus/RequestExecutingEvent.cs rename to src/SecTester.Repeater/Bus/IncomingRequest.cs index 73855e4..4a6dd2f 100644 --- a/src/SecTester.Repeater/Bus/RequestExecutingEvent.cs +++ b/src/SecTester.Repeater/Bus/IncomingRequest.cs @@ -1,19 +1,14 @@ using System; using System.Collections.Generic; using System.Net.Http; -using System.Text.Json.Serialization; -using System.Text.RegularExpressions; using SecTester.Core.Bus; using SecTester.Repeater.Runners; namespace SecTester.Repeater.Bus; -[MessageType(name: "ExecuteScript")] -public record RequestExecutingEvent(Uri Url) : Event, IRequest +public record IncomingRequest(Uri Url) : Event, IRequest { public string? Body { get; init; } - [JsonPropertyName("correlation_id_regex")] - public Regex? CorrelationIdRegex { get; init; } public HttpMethod Method { get; init; } = HttpMethod.Get; public Protocol Protocol { get; init; } = Protocol.Http; public Uri Url { get; init; } = Url ?? throw new ArgumentNullException(nameof(Url)); diff --git a/src/SecTester.Repeater/Bus/RequestExecutingResult.cs b/src/SecTester.Repeater/Bus/OutgoingResponse.cs similarity index 62% rename from src/SecTester.Repeater/Bus/RequestExecutingResult.cs rename to src/SecTester.Repeater/Bus/OutgoingResponse.cs index 4f72b38..36a01d1 100644 --- a/src/SecTester.Repeater/Bus/RequestExecutingResult.cs +++ b/src/SecTester.Repeater/Bus/OutgoingResponse.cs @@ -1,17 +1,16 @@ using System.Collections.Generic; -using System.Text.Json.Serialization; using SecTester.Repeater.Runners; namespace SecTester.Repeater.Bus; -public record RequestExecutingResult : IResponse +public record OutgoingResponse : IResponse { - [JsonPropertyName("status_code")] public int? StatusCode { get; init; } + public int? StatusCode { get; init; } public string? Body { get; init; } public string? Message { get; init; } - [JsonPropertyName("error_code")] public string? ErrorCode { get; init; } + public string? ErrorCode { get; init; } public Protocol Protocol { get; init; } = Protocol.Http; diff --git a/src/SecTester.Repeater/Bus/RegisterRepeaterCommand.cs b/src/SecTester.Repeater/Bus/RegisterRepeaterCommand.cs deleted file mode 100644 index ad3a94a..0000000 --- a/src/SecTester.Repeater/Bus/RegisterRepeaterCommand.cs +++ /dev/null @@ -1,6 +0,0 @@ -using SecTester.Core.Bus; - -namespace SecTester.Repeater.Bus; - -[MessageType(name: "RepeaterRegistering")] -public record RegisterRepeaterCommand(string Version, string RepeaterId) : Command; diff --git a/src/SecTester.Repeater/Bus/RegisterRepeaterPayload.cs b/src/SecTester.Repeater/Bus/RegisterRepeaterPayload.cs deleted file mode 100644 index 38c27ad..0000000 --- a/src/SecTester.Repeater/Bus/RegisterRepeaterPayload.cs +++ /dev/null @@ -1,3 +0,0 @@ -namespace SecTester.Repeater.Bus; - -public record RegisterRepeaterPayload(string? Version = default, RepeaterRegisteringError Error = RepeaterRegisteringError.None); diff --git a/src/SecTester.Repeater/Bus/RegisterRepeaterResult.cs b/src/SecTester.Repeater/Bus/RegisterRepeaterResult.cs deleted file mode 100644 index 82b182d..0000000 --- a/src/SecTester.Repeater/Bus/RegisterRepeaterResult.cs +++ /dev/null @@ -1,3 +0,0 @@ -namespace SecTester.Repeater.Bus; - -public record RegisterRepeaterResult(RegisterRepeaterPayload Payload); diff --git a/src/SecTester.Repeater/Bus/RepeaterRegisteringError.cs b/src/SecTester.Repeater/Bus/RepeaterRegisteringError.cs deleted file mode 100644 index 8aa6a8f..0000000 --- a/src/SecTester.Repeater/Bus/RepeaterRegisteringError.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace SecTester.Repeater.Bus; - -public enum RepeaterRegisteringError -{ - NotActive, - Busy, - RequiresToBeUpdated, - NotFound, - None -} diff --git a/src/SecTester.Repeater/Bus/RepeaterStatusEvent.cs b/src/SecTester.Repeater/Bus/RepeaterStatusEvent.cs deleted file mode 100644 index d8bc9ee..0000000 --- a/src/SecTester.Repeater/Bus/RepeaterStatusEvent.cs +++ /dev/null @@ -1,6 +0,0 @@ -using SecTester.Core.Bus; - -namespace SecTester.Repeater.Bus; - -[MessageType(name: "RepeaterStatusUpdated")] -public record RepeaterStatusEvent(string RepeaterId, RepeaterStatus Status) : Event; diff --git a/src/SecTester.Repeater/Bus/RequestExecutingEventListener.cs b/src/SecTester.Repeater/Bus/RequestExecutingEventListener.cs deleted file mode 100644 index 19d1cf3..0000000 --- a/src/SecTester.Repeater/Bus/RequestExecutingEventListener.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Threading.Tasks; -using SecTester.Core.Bus; -using SecTester.Repeater.Runners; - -namespace SecTester.Repeater.Bus; - -public delegate IRequestRunner? RequestRunnerResolver(Protocol key); - -public class RequestExecutingEventListener : IEventListener -{ - private readonly RequestRunnerResolver _requestRunnersAccessor; - - public RequestExecutingEventListener(RequestRunnerResolver requestRunnersAccessor) - { - _requestRunnersAccessor = requestRunnersAccessor; - } - - public async Task Handle(RequestExecutingEvent message) - { - var runner = _requestRunnersAccessor(message.Protocol); - - if (runner == null) - { - throw new InvalidOperationException($"Unsupported protocol {message.Protocol}"); - } - - return (RequestExecutingResult)(await runner.Run(message).ConfigureAwait(false)); - } -} diff --git a/src/SecTester.Repeater/Bus/SocketIoRepeaterBus.cs b/src/SecTester.Repeater/Bus/SocketIoRepeaterBus.cs new file mode 100644 index 0000000..b405686 --- /dev/null +++ b/src/SecTester.Repeater/Bus/SocketIoRepeaterBus.cs @@ -0,0 +1,136 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using System.Timers; +using Microsoft.Extensions.Logging; +using SecTester.Core.Utils; + +namespace SecTester.Repeater.Bus; + +public class SocketIoRepeaterBus : IRepeaterBus +{ + private static readonly TimeSpan PingInterval = TimeSpan.FromSeconds(10); + private readonly ITimerProvider _heartbeat; + private SocketIOClient.SocketIO _client; + private readonly ILogger _logger; + private readonly Uri _url; + + public SocketIoRepeaterBus(Uri url, SocketIOClient.SocketIO client, ITimerProvider heartbeat, ILogger logger) + { + _url = url ?? throw new ArgumentNullException(nameof(url)); + _client = client ?? throw new ArgumentNullException(nameof(client)); + _heartbeat = heartbeat ?? throw new ArgumentNullException(nameof(heartbeat)); + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + } + + private record RepeaterVersion(string Version); + private record RepeaterError(string Message); + + private record RepeaterDeployed(string RepeaterId); + + public event Func>? RequestReceived; + public event Action? ErrorOccurred; + public event Action? UpgradeAvailable; + + public async Task Connect() + { + if (_client is not { Connected: true }) + { + DelegateEvents(); + + await _client.ConnectAsync().ConfigureAwait(false); + + await SchedulePing().ConfigureAwait(false); + + _logger.LogDebug("Repeater connected to {Url}", _url); + } + } + + private void DelegateEvents() + { + _client.On("error", response => + { + var err = response.GetValue(); + ErrorOccurred?.Invoke(new(err.Message)); + }); + + _client.On("update-available", response => + { + var version = response.GetValue(); + UpgradeAvailable?.Invoke(new(version.Version)); + }); + + _client.On("request", async response => + { + var request = response.GetValue(); + + if (RequestReceived != null) + { + var result = await RequestReceived.Invoke(request).ConfigureAwait(false); + await response.CallbackAsync(result).ConfigureAwait(false); + } + }); + } + + public async ValueTask DisposeAsync() + { + if (_client is { Connected: true }) + { + _heartbeat.Elapsed -= Ping; + _heartbeat.Stop(); + await _client.DisconnectAsync().ConfigureAwait(false); + _logger.LogDebug("Repeater disconnected from {Url}", _url); + } + + _client.Dispose(); + + RequestReceived = null; + ErrorOccurred = null; + UpgradeAvailable = null; + + GC.SuppressFinalize(this); + } + + public async Task Deploy(string repeaterId, Runtime? runtime = null, CancellationToken? cancellationToken = null) + { + try + { + var tcs = new TaskCompletionSource(); + + _client.On("deployed", response => tcs.TrySetResult(response.GetValue())); + + await _client.EmitAsync("deploy", new + { + RepeaterId = repeaterId + }, runtime, cancellationToken).ConfigureAwait(false); + + using var _ = cancellationToken?.Register(() => tcs.TrySetCanceled()); + + var result = await tcs.Task.ConfigureAwait(false); + + _logger.LogDebug("Repeater ({RepeaterId}) deployed", result?.RepeaterId); + } + finally + { + _client.Off("deployed"); + } + } + + private async Task SchedulePing() + { + await Ping().ConfigureAwait(false); + _heartbeat.Interval = PingInterval.TotalMilliseconds; + _heartbeat.Elapsed += Ping; + _heartbeat.Start(); + } + + private async void Ping(object sender, ElapsedEventArgs args) + { + await Ping().ConfigureAwait(false); + } + + private async Task Ping() + { + await _client.EmitAsync("ping").ConfigureAwait(false); + } +} diff --git a/src/SecTester.Repeater/DefaultRepeaterFactory.cs b/src/SecTester.Repeater/DefaultRepeaterFactory.cs index 6ea5264..cd0a8e6 100644 --- a/src/SecTester.Repeater/DefaultRepeaterFactory.cs +++ b/src/SecTester.Repeater/DefaultRepeaterFactory.cs @@ -1,10 +1,8 @@ using System; using System.Threading.Tasks; -using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using SecTester.Core; using SecTester.Core.Logger; -using SecTester.Core.Utils; using SecTester.Repeater.Api; using SecTester.Repeater.Bus; @@ -13,20 +11,20 @@ namespace SecTester.Repeater; public class DefaultRepeaterFactory : IRepeaterFactory { private readonly Configuration _configuration; - private readonly IRepeaterEventBusFactory _eventBusFactory; + private readonly IRepeaterBusFactory _busFactory; private readonly IRepeaters _repeaters; - private readonly IServiceScopeFactory _scopeFactory; private readonly ILoggerFactory _loggerFactory; private readonly IAnsiCodeColorizer _ansiCodeColorizer; + private readonly RequestRunnerResolver _requestRunnerResolver; - public DefaultRepeaterFactory(IServiceScopeFactory scopeFactory, IRepeaters repeaters, IRepeaterEventBusFactory eventBusFactory, Configuration configuration, ILoggerFactory loggerFactory, IAnsiCodeColorizer ansiCodeColorizer) + public DefaultRepeaterFactory(IRepeaters repeaters, IRepeaterBusFactory busFactory, Configuration configuration, ILoggerFactory loggerFactory, IAnsiCodeColorizer ansiCodeColorizer, RequestRunnerResolver requestRunnerResolver) { - _scopeFactory = scopeFactory ?? throw new ArgumentNullException(nameof(scopeFactory)); _repeaters = repeaters ?? throw new ArgumentNullException(nameof(repeaters)); _loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory)); - _eventBusFactory = eventBusFactory ?? throw new ArgumentNullException(nameof(eventBusFactory)); + _busFactory = busFactory ?? throw new ArgumentNullException(nameof(busFactory)); _configuration = configuration ?? throw new ArgumentNullException(nameof(configuration)); _ansiCodeColorizer = ansiCodeColorizer ?? throw new ArgumentNullException(nameof(ansiCodeColorizer)); + _requestRunnerResolver = requestRunnerResolver ?? throw new ArgumentNullException(nameof(requestRunnerResolver)); } public async Task CreateRepeater(RepeaterOptions? options = default) @@ -34,12 +32,10 @@ public async Task CreateRepeater(RepeaterOptions? options = default) options ??= new RepeaterOptions(); string repeaterId = await _repeaters.CreateRepeater($"{options.NamePrefix}-{Guid.NewGuid()}", options.Description).ConfigureAwait(false); - var eventBus = _eventBusFactory.Create(repeaterId); - var scope = _scopeFactory.CreateAsyncScope(); - var timerProvider = scope.ServiceProvider.GetRequiredService(); + var bus = _busFactory.Create(repeaterId); var version = new Version(_configuration.RepeaterVersion); - return new Repeater(repeaterId, eventBus, version, _loggerFactory.CreateLogger(), timerProvider, _ansiCodeColorizer); + return new Repeater(repeaterId, bus, version, _loggerFactory.CreateLogger(), _ansiCodeColorizer, _requestRunnerResolver); } } diff --git a/src/SecTester.Repeater/Extensions/ServiceCollectionExtensions.cs b/src/SecTester.Repeater/Extensions/ServiceCollectionExtensions.cs index da2383e..eaa0dd6 100644 --- a/src/SecTester.Repeater/Extensions/ServiceCollectionExtensions.cs +++ b/src/SecTester.Repeater/Extensions/ServiceCollectionExtensions.cs @@ -21,8 +21,7 @@ public static IServiceCollection AddSecTesterRepeater(this IServiceCollection co { return collection .AddSingleton(options) - .AddSingleton() - .AddScoped() + .AddSingleton() .AddScoped() .AddScoped() .AddScoped() diff --git a/src/SecTester.Repeater/Repeater.cs b/src/SecTester.Repeater/Repeater.cs index 2ff8040..4028a2d 100644 --- a/src/SecTester.Repeater/Repeater.cs +++ b/src/SecTester.Repeater/Repeater.cs @@ -2,33 +2,34 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Logging; -using SecTester.Core.Bus; using SecTester.Core.Exceptions; using SecTester.Core.Extensions; using SecTester.Core.Logger; -using SecTester.Core.Utils; using SecTester.Repeater.Bus; +using SecTester.Repeater.Runners; namespace SecTester.Repeater; +public delegate IRequestRunner? RequestRunnerResolver(Protocol key); + + public class Repeater : IRepeater { - private static readonly TimeSpan DefaultPingInterval = TimeSpan.FromSeconds(10); - private readonly IEventBus _eventBus; - private readonly ITimerProvider _heartbeat; + private readonly IRepeaterBus _bus; private readonly ILogger _logger; private readonly SemaphoreSlim _semaphore = new(1, 1); private readonly Version _version; private readonly IAnsiCodeColorizer _ansiCodeColorizer; + private readonly RequestRunnerResolver _requestRunnersAccessor; - public Repeater(string repeaterId, IEventBus eventBus, Version version, ILogger logger, ITimerProvider heartbeat, - IAnsiCodeColorizer ansiCodeColorizer) + public Repeater(string repeaterId, IRepeaterBus bus, Version version, ILogger logger, + IAnsiCodeColorizer ansiCodeColorizer, RequestRunnerResolver requestRunnersAccessor) { RepeaterId = repeaterId ?? throw new ArgumentNullException(nameof(repeaterId)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _version = version ?? throw new ArgumentNullException(nameof(version)); - _eventBus = eventBus ?? throw new ArgumentNullException(nameof(eventBus)); - _heartbeat = heartbeat ?? throw new ArgumentNullException(nameof(heartbeat)); + _bus = bus ?? throw new ArgumentNullException(nameof(bus)); + _requestRunnersAccessor = requestRunnersAccessor ?? throw new ArgumentNullException(nameof(requestRunnersAccessor)); _ansiCodeColorizer = ansiCodeColorizer ?? throw new ArgumentNullException(nameof(ansiCodeColorizer)); } @@ -57,9 +58,10 @@ public async Task Start(CancellationToken cancellationToken = default) Status = RunningStatus.Starting; - await Register().ConfigureAwait(false); SubscribeToEvents(); - await SchedulePing().ConfigureAwait(false); + + await _bus.Connect().ConfigureAwait(false); + await _bus.Deploy(RepeaterId, new Runtime(_version.ToString()), cancellationToken).ConfigureAwait(false); Status = RunningStatus.Running; } @@ -70,44 +72,14 @@ public async Task Start(CancellationToken cancellationToken = default) } } - private void SubscribeToEvents() - { - _eventBus.Register(); - } - - private async Task SchedulePing() - { - await SendStatus(RepeaterStatus.Connected).ConfigureAwait(false); - _heartbeat.Interval = DefaultPingInterval.TotalMilliseconds; - _heartbeat.Elapsed += async (_, _) => await SendStatus(RepeaterStatus.Connected).ConfigureAwait(false); - _heartbeat.Start(); - } - - private async Task SendStatus(RepeaterStatus status) - { - var @event = new RepeaterStatusEvent(RepeaterId, status); - await _eventBus.Publish(@event).ConfigureAwait(false); - } - - private async Task Register() - { - var command = new RegisterRepeaterCommand(_version.ToString(), RepeaterId); - var res = await _eventBus.Execute(command).ConfigureAwait(false); - - if (res == null) - { - throw new SecTesterException("Error registering repeater."); - } - - EnsureRegistrationStatus(res.Payload); - } - public async Task Stop(CancellationToken cancellationToken = default) { using var _ = await _semaphore.LockAsync(cancellationToken).ConfigureAwait(false); try { + UnsubscribeFromEvents(); + if (Status != RunningStatus.Running) { return; @@ -115,9 +87,7 @@ public async Task Stop(CancellationToken cancellationToken = default) Status = RunningStatus.Off; - _heartbeat.Stop(); - await SendStatus(RepeaterStatus.Disconnected).ConfigureAwait(false); - _eventBus.Dispose(); + await _bus.DisposeAsync().ConfigureAwait(false); } catch { @@ -125,33 +95,43 @@ public async Task Stop(CancellationToken cancellationToken = default) } } - private void EnsureRegistrationStatus(RegisterRepeaterPayload result) + public async Task HandleIncomingRequest(IncomingRequest message) { - if (result.Error != RepeaterRegisteringError.None) + var runner = _requestRunnersAccessor(message.Protocol); + + if (runner == null) { - HandleRegisterError(result.Error); + throw new InvalidOperationException($"Unsupported protocol {message.Protocol}"); } - else + + return (OutgoingResponse)(await runner.Run(message).ConfigureAwait(false)); + } + + private void SubscribeToEvents() + { + _bus.RequestReceived += HandleIncomingRequest; + _bus.ErrorOccurred += HandleRegisterError; + _bus.UpgradeAvailable += HandleUpgradeAvailable; + } + + private void UnsubscribeFromEvents() + { + _bus.RequestReceived -= HandleIncomingRequest; + _bus.ErrorOccurred -= HandleRegisterError; + _bus.UpgradeAvailable -= HandleUpgradeAvailable; + } + + private void HandleUpgradeAvailable(Version version) + { + if (version.CompareTo(_version) != 0) { - if (new Version(result.Version!).CompareTo(_version) != 0) - { - _logger.LogWarning("{Prefix}: A new Repeater version ({Version}) is available, please update SecTester", - _ansiCodeColorizer.Colorize(AnsiCodeColor.Yellow, "(!) IMPORTANT"), result.Version); - } + _logger.LogWarning("{Prefix}: A new Repeater version ({Version}) is available, please update SecTester", + _ansiCodeColorizer.Colorize(AnsiCodeColor.Yellow, "(!) IMPORTANT"), version); } } - private void HandleRegisterError(RepeaterRegisteringError error) + private void HandleRegisterError(Exception error) { - throw error switch - { - RepeaterRegisteringError.NotActive => new SecTesterException("Access Refused: The current Repeater is not active."), - RepeaterRegisteringError.NotFound => new SecTesterException("Unauthorized access. Please check your credentials."), - RepeaterRegisteringError.Busy => new SecTesterException( - $"Access Refused: There is an already running Repeater with ID {RepeaterId}"), - RepeaterRegisteringError.RequiresToBeUpdated => new SecTesterException( - $"{_ansiCodeColorizer.Colorize(AnsiCodeColor.Red, "(!) CRITICAL")}: The current running version is no longer supported, please update SecTester."), - _ => new ArgumentOutOfRangeException(nameof(error), error, "Something went wrong. Unknown error.") - }; + throw new SecTesterException(error.Message); } } diff --git a/src/SecTester.Repeater/Runners/HttpRequestRunner.cs b/src/SecTester.Repeater/Runners/HttpRequestRunner.cs index 7945067..366b00c 100644 --- a/src/SecTester.Repeater/Runners/HttpRequestRunner.cs +++ b/src/SecTester.Repeater/Runners/HttpRequestRunner.cs @@ -48,7 +48,7 @@ public async Task Run(IRequest request) } catch (Exception err) { - return new RequestExecutingResult + return new OutgoingResponse { Message = err.Message, // TODO: use native errno codes instead @@ -57,7 +57,7 @@ public async Task Run(IRequest request) } } - private async Task CreateRequestExecutingResult(HttpResponseMessage response) + private async Task CreateRequestExecutingResult(HttpResponseMessage response) { var body = await TruncateResponseBody(response).ConfigureAwait(false); var headers = AggregateHeaders(response); @@ -71,7 +71,7 @@ private async Task CreateRequestExecutingResult(HttpResp headers.Replace(contentLength, x => x.Key.Equals(ContentLengthFieldName, StringComparison.OrdinalIgnoreCase)); } - return new RequestExecutingResult + return new OutgoingResponse { Headers = headers, StatusCode = (int)response.StatusCode, diff --git a/src/SecTester.Repeater/Runtime.cs b/src/SecTester.Repeater/Runtime.cs new file mode 100644 index 0000000..4841f6a --- /dev/null +++ b/src/SecTester.Repeater/Runtime.cs @@ -0,0 +1,12 @@ +namespace SecTester.Repeater; + +public record Runtime(string Version) +{ + public bool? ScriptsLoaded { get; init; } + public string? Ci { get; init; } + public string? Os { get; init; } + public string? Arch { get; init; } + public bool? Docker { get; init; } + public string? Distribution { get; init; } + public string? NetVersion { get; init; } +} diff --git a/src/SecTester.Repeater/SecTester.Repeater.csproj b/src/SecTester.Repeater/SecTester.Repeater.csproj index e40d8f9..15eb7f1 100644 --- a/src/SecTester.Repeater/SecTester.Repeater.csproj +++ b/src/SecTester.Repeater/SecTester.Repeater.csproj @@ -11,6 +11,8 @@ + + diff --git a/src/SecTester.Repeater/packages.lock.json b/src/SecTester.Repeater/packages.lock.json index a956db0..f4301ee 100644 --- a/src/SecTester.Repeater/packages.lock.json +++ b/src/SecTester.Repeater/packages.lock.json @@ -21,6 +21,28 @@ "Microsoft.NETCore.Platforms": "1.1.0" } }, + "SocketIO.Serializer.MessagePack": { + "type": "Direct", + "requested": "[3.1.1, )", + "resolved": "3.1.1", + "contentHash": "lOAZs6AUCDhfMFa4Vu40LeeK/9fP+iMUerI3qzmToDaSa+A2/YQ7D0nvYa1atwTvzvhDZklBKNV5dIzQWWwPJg==", + "dependencies": { + "MessagePack": "2.5.124", + "SocketIO.Core": "3.1.1", + "SocketIO.Serializer.Core": "3.1.1" + } + }, + "SocketIOClient": { + "type": "Direct", + "requested": "[3.1.1, )", + "resolved": "3.1.1", + "contentHash": "g8Lauia1Cj5DBXeC9j6vDSJeQEboGmXsnduW06VOBMe+UgqCrenxszYXJg19rAjwO10XRWQorOuU1XNMfYo8Xg==", + "dependencies": { + "SocketIO.Serializer.Core": "3.1.1", + "SocketIO.Serializer.SystemTextJson": "3.1.1", + "System.Collections": "4.3.0" + } + }, "System.Linq.Async": { "type": "Direct", "requested": "[6.0.1, )", @@ -39,6 +61,26 @@ "System.Text.Json": "6.0.0" } }, + "MessagePack": { + "type": "Transitive", + "resolved": "2.5.124", + "contentHash": "jxJPIkCnKwZcg9qtN1WoR99nlcJl/y/HYOTQLxnyXzR4iE5xhZviCPSKXLe08fcF9Tk4hP7mm+mVVdyUfh2ALw==", + "dependencies": { + "MessagePack.Annotations": "2.5.124", + "Microsoft.Bcl.AsyncInterfaces": "6.0.0", + "Microsoft.NET.StringTools": "17.6.3", + "System.Collections.Immutable": "6.0.0", + "System.Reflection.Emit": "4.7.0", + "System.Reflection.Emit.Lightweight": "4.7.0", + "System.Runtime.CompilerServices.Unsafe": "6.0.0", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "MessagePack.Annotations": { + "type": "Transitive", + "resolved": "2.5.124", + "contentHash": "YTWbSjVlMhe6WaEQ953rrNagRzQxDrp9mCB3W2Yr1TOITlaEv/ZMFvqZSabSs09Gy86Kq7BmvcxKTodv/YNDQA==" + }, "Microsoft.Bcl.AsyncInterfaces": { "type": "Transitive", "resolved": "7.0.0", @@ -177,11 +219,25 @@ "System.Runtime.CompilerServices.Unsafe": "6.0.0" } }, + "Microsoft.NET.StringTools": { + "type": "Transitive", + "resolved": "17.6.3", + "contentHash": "N0ZIanl1QCgvUumEL1laasU0a7sOE5ZwLZVTn0pAePnfhq8P7SvTjF8Axq+CnavuQkmdQpGNXQ1efZtu5kDFbA==", + "dependencies": { + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, "Microsoft.NETCore.Platforms": { "type": "Transitive", "resolved": "1.1.0", "contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==" }, + "Microsoft.NETCore.Targets": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "aOZA3BWfz9RXjpzt0sRJJMjAscAUm3Hoa4UWAfceV9UTYxgwZ1lZt5nO2myFf+/jetYQo4uTP7zS8sJY67BBxg==" + }, "RabbitMQ.Client": { "type": "Transitive", "resolved": "6.4.0", @@ -191,11 +247,53 @@ "System.Threading.Channels": "4.7.1" } }, + "SocketIO.Core": { + "type": "Transitive", + "resolved": "3.1.1", + "contentHash": "L5GSyODDjlub5YdDxfsRtA9uxBNw1Hs/egEMhdOGFyD0c63VmvWQ1A4Gfc4GYKYInz1muP4C8QNblXErnUYDqA==" + }, + "SocketIO.Serializer.Core": { + "type": "Transitive", + "resolved": "3.1.1", + "contentHash": "aFanlt2GOGEy7GTGLyh8f8SwhtmQwoPOHTAYCQ0brjg05Nb3F38sk4hYogpII5imyZ7w0spqwNHwpl7FZ49HOA==", + "dependencies": { + "SocketIO.Core": "3.1.1" + } + }, + "SocketIO.Serializer.SystemTextJson": { + "type": "Transitive", + "resolved": "3.1.1", + "contentHash": "1PKQ+hOAJ4l3ZXlrVgiB3uNY3kLhjzYjnxk/97V6npJrNmhq09Di2EQSpGweQMu6KPbOxjZ7eYVARkGTWIUsjg==", + "dependencies": { + "SocketIO.Core": "3.1.1", + "SocketIO.Serializer.Core": "3.1.1", + "System.Text.Json": "7.0.3" + } + }, "System.Buffers": { "type": "Transitive", "resolved": "4.5.1", "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" }, + "System.Collections": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "3Dcj85/TBdVpL5Zr+gEEBUuFe2icOnLalmEh9hfck1PTYbbyWuZgh4fmm2ysCLTrqLQw6t3TgTyJ+VLp+Qb+Lw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Collections.Immutable": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "l4zZJ1WU2hqpQQHXz1rvC3etVZN+2DLmQMO79FhOTZHMn8tDRr+WU287sbomD0BETlmKDn0ygUgVy9k5xkkJdA==", + "dependencies": { + "System.Memory": "4.5.4", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, "System.ComponentModel.Annotations": { "type": "Transitive", "resolved": "5.0.0", @@ -212,8 +310,8 @@ }, "System.Memory": { "type": "Transitive", - "resolved": "4.5.4", - "contentHash": "1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw==", + "resolved": "4.5.5", + "contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==", "dependencies": { "System.Buffers": "4.5.1", "System.Numerics.Vectors": "4.4.0", @@ -225,6 +323,14 @@ "resolved": "4.5.0", "contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==" }, + "System.Reflection.Emit": { + "type": "Transitive", + "resolved": "4.7.0", + "contentHash": "VR4kk8XLKebQ4MZuKuIni/7oh+QGFmZW3qORd1GvBq/8026OpW501SzT/oypwiQl4TvT8ErnReh/NzY9u+C6wQ==", + "dependencies": { + "System.Reflection.Emit.ILGeneration": "4.7.0" + } + }, "System.Reflection.Emit.ILGeneration": { "type": "Transitive", "resolved": "4.7.0", @@ -238,6 +344,15 @@ "System.Reflection.Emit.ILGeneration": "4.7.0" } }, + "System.Runtime": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "JufQi0vPQ0xGnAczR13AUFglDyVYt4Kqnz1AZaiKZ5+GICq0/1MH/mO/eAJHt/mHW1zjKBJd7kV26SrxddAhiw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0" + } + }, "System.Runtime.CompilerServices.Unsafe": { "type": "Transitive", "resolved": "6.0.0", @@ -245,25 +360,25 @@ }, "System.Text.Encodings.Web": { "type": "Transitive", - "resolved": "6.0.0", - "contentHash": "Vg8eB5Tawm1IFqj4TVK1czJX89rhFxJo9ELqc/Eiq0eXy13RK00eubyU6TJE6y+GQXjyV5gSfiewDUZjQgSE0w==", + "resolved": "7.0.0", + "contentHash": "OP6umVGxc0Z0MvZQBVigj4/U31Pw72ITihDWP9WiWDm+q5aoe0GaJivsfYGq53o6dxH7DcXWiCTl7+0o2CGdmg==", "dependencies": { "System.Buffers": "4.5.1", - "System.Memory": "4.5.4", + "System.Memory": "4.5.5", "System.Runtime.CompilerServices.Unsafe": "6.0.0" } }, "System.Text.Json": { "type": "Transitive", - "resolved": "6.0.0", - "contentHash": "zaJsHfESQvJ11vbXnNlkrR46IaMULk/gHxYsJphzSF+07kTjPHv+Oc14w6QEOfo3Q4hqLJgStUaYB9DBl0TmWg==", + "resolved": "7.0.3", + "contentHash": "AyjhwXN1zTFeIibHimfJn6eAsZ7rTBib79JQpzg8WAuR/HKDu9JGNHTuu3nbbXQ/bgI+U4z6HtZmCHNXB1QXrQ==", "dependencies": { - "Microsoft.Bcl.AsyncInterfaces": "6.0.0", + "Microsoft.Bcl.AsyncInterfaces": "7.0.0", "System.Buffers": "4.5.1", - "System.Memory": "4.5.4", + "System.Memory": "4.5.5", "System.Numerics.Vectors": "4.5.0", "System.Runtime.CompilerServices.Unsafe": "6.0.0", - "System.Text.Encodings.Web": "6.0.0", + "System.Text.Encodings.Web": "7.0.0", "System.Threading.Tasks.Extensions": "4.5.4" } }, @@ -300,7 +415,7 @@ "Microsoft.Extensions.DependencyInjection.Abstractions": "[6.0.0, )", "Microsoft.Extensions.Http": "[6.0.0, )", "RabbitMQ.Client": "[6.4.0, )", - "SecTester.Core": "[0.26.0, )", + "SecTester.Core": "[0.40.0, )", "System.Text.Json": "[6.0.0, )", "System.Threading.RateLimiting": "[7.0.0, )" } diff --git a/src/SecTester.Reporter/packages.lock.json b/src/SecTester.Reporter/packages.lock.json index abf7a2f..544e7cd 100644 --- a/src/SecTester.Reporter/packages.lock.json +++ b/src/SecTester.Reporter/packages.lock.json @@ -299,7 +299,7 @@ "Microsoft.Extensions.DependencyInjection.Abstractions": "[6.0.0, )", "Microsoft.Extensions.Http": "[6.0.0, )", "RabbitMQ.Client": "[6.4.0, )", - "SecTester.Core": "[0.29.2, )", + "SecTester.Core": "[0.40.0, )", "System.Text.Json": "[6.0.0, )", "System.Threading.RateLimiting": "[7.0.0, )" } @@ -317,8 +317,8 @@ "dependencies": { "Macross.Json.Extensions": "[3.0.0, )", "Microsoft.Extensions.DependencyInjection.Abstractions": "[6.0.0, )", - "SecTester.Bus": "[0.29.2, )", - "SecTester.Core": "[0.29.2, )", + "SecTester.Bus": "[0.40.0, )", + "SecTester.Core": "[0.40.0, )", "System.Linq.Async": "[6.0.1, )", "System.Text.Json": "[6.0.0, )" } diff --git a/src/SecTester.Runner/packages.lock.json b/src/SecTester.Runner/packages.lock.json index 843f681..0213610 100644 --- a/src/SecTester.Runner/packages.lock.json +++ b/src/SecTester.Runner/packages.lock.json @@ -30,6 +30,26 @@ "System.Text.Json": "6.0.0" } }, + "MessagePack": { + "type": "Transitive", + "resolved": "2.5.124", + "contentHash": "jxJPIkCnKwZcg9qtN1WoR99nlcJl/y/HYOTQLxnyXzR4iE5xhZviCPSKXLe08fcF9Tk4hP7mm+mVVdyUfh2ALw==", + "dependencies": { + "MessagePack.Annotations": "2.5.124", + "Microsoft.Bcl.AsyncInterfaces": "6.0.0", + "Microsoft.NET.StringTools": "17.6.3", + "System.Collections.Immutable": "6.0.0", + "System.Reflection.Emit": "4.7.0", + "System.Reflection.Emit.Lightweight": "4.7.0", + "System.Runtime.CompilerServices.Unsafe": "6.0.0", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "MessagePack.Annotations": { + "type": "Transitive", + "resolved": "2.5.124", + "contentHash": "YTWbSjVlMhe6WaEQ953rrNagRzQxDrp9mCB3W2Yr1TOITlaEv/ZMFvqZSabSs09Gy86Kq7BmvcxKTodv/YNDQA==" + }, "Microsoft.Bcl.AsyncInterfaces": { "type": "Transitive", "resolved": "7.0.0", @@ -168,11 +188,25 @@ "System.Runtime.CompilerServices.Unsafe": "6.0.0" } }, + "Microsoft.NET.StringTools": { + "type": "Transitive", + "resolved": "17.6.3", + "contentHash": "N0ZIanl1QCgvUumEL1laasU0a7sOE5ZwLZVTn0pAePnfhq8P7SvTjF8Axq+CnavuQkmdQpGNXQ1efZtu5kDFbA==", + "dependencies": { + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, "Microsoft.NETCore.Platforms": { "type": "Transitive", "resolved": "1.1.0", "contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==" }, + "Microsoft.NETCore.Targets": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "aOZA3BWfz9RXjpzt0sRJJMjAscAUm3Hoa4UWAfceV9UTYxgwZ1lZt5nO2myFf+/jetYQo4uTP7zS8sJY67BBxg==" + }, "RabbitMQ.Client": { "type": "Transitive", "resolved": "6.4.0", @@ -182,11 +216,73 @@ "System.Threading.Channels": "4.7.1" } }, + "SocketIO.Core": { + "type": "Transitive", + "resolved": "3.1.1", + "contentHash": "L5GSyODDjlub5YdDxfsRtA9uxBNw1Hs/egEMhdOGFyD0c63VmvWQ1A4Gfc4GYKYInz1muP4C8QNblXErnUYDqA==" + }, + "SocketIO.Serializer.Core": { + "type": "Transitive", + "resolved": "3.1.1", + "contentHash": "aFanlt2GOGEy7GTGLyh8f8SwhtmQwoPOHTAYCQ0brjg05Nb3F38sk4hYogpII5imyZ7w0spqwNHwpl7FZ49HOA==", + "dependencies": { + "SocketIO.Core": "3.1.1" + } + }, + "SocketIO.Serializer.MessagePack": { + "type": "Transitive", + "resolved": "3.1.1", + "contentHash": "lOAZs6AUCDhfMFa4Vu40LeeK/9fP+iMUerI3qzmToDaSa+A2/YQ7D0nvYa1atwTvzvhDZklBKNV5dIzQWWwPJg==", + "dependencies": { + "MessagePack": "2.5.124", + "SocketIO.Core": "3.1.1", + "SocketIO.Serializer.Core": "3.1.1" + } + }, + "SocketIO.Serializer.SystemTextJson": { + "type": "Transitive", + "resolved": "3.1.1", + "contentHash": "1PKQ+hOAJ4l3ZXlrVgiB3uNY3kLhjzYjnxk/97V6npJrNmhq09Di2EQSpGweQMu6KPbOxjZ7eYVARkGTWIUsjg==", + "dependencies": { + "SocketIO.Core": "3.1.1", + "SocketIO.Serializer.Core": "3.1.1", + "System.Text.Json": "7.0.3" + } + }, + "SocketIOClient": { + "type": "Transitive", + "resolved": "3.1.1", + "contentHash": "g8Lauia1Cj5DBXeC9j6vDSJeQEboGmXsnduW06VOBMe+UgqCrenxszYXJg19rAjwO10XRWQorOuU1XNMfYo8Xg==", + "dependencies": { + "SocketIO.Serializer.Core": "3.1.1", + "SocketIO.Serializer.SystemTextJson": "3.1.1", + "System.Collections": "4.3.0" + } + }, "System.Buffers": { "type": "Transitive", "resolved": "4.5.1", "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" }, + "System.Collections": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "3Dcj85/TBdVpL5Zr+gEEBUuFe2icOnLalmEh9hfck1PTYbbyWuZgh4fmm2ysCLTrqLQw6t3TgTyJ+VLp+Qb+Lw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Collections.Immutable": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "l4zZJ1WU2hqpQQHXz1rvC3etVZN+2DLmQMO79FhOTZHMn8tDRr+WU287sbomD0BETlmKDn0ygUgVy9k5xkkJdA==", + "dependencies": { + "System.Memory": "4.5.4", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, "System.ComponentModel.Annotations": { "type": "Transitive", "resolved": "5.0.0", @@ -211,8 +307,8 @@ }, "System.Memory": { "type": "Transitive", - "resolved": "4.5.4", - "contentHash": "1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw==", + "resolved": "4.5.5", + "contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==", "dependencies": { "System.Buffers": "4.5.1", "System.Numerics.Vectors": "4.4.0", @@ -224,6 +320,14 @@ "resolved": "4.5.0", "contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==" }, + "System.Reflection.Emit": { + "type": "Transitive", + "resolved": "4.7.0", + "contentHash": "VR4kk8XLKebQ4MZuKuIni/7oh+QGFmZW3qORd1GvBq/8026OpW501SzT/oypwiQl4TvT8ErnReh/NzY9u+C6wQ==", + "dependencies": { + "System.Reflection.Emit.ILGeneration": "4.7.0" + } + }, "System.Reflection.Emit.ILGeneration": { "type": "Transitive", "resolved": "4.7.0", @@ -237,6 +341,15 @@ "System.Reflection.Emit.ILGeneration": "4.7.0" } }, + "System.Runtime": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "JufQi0vPQ0xGnAczR13AUFglDyVYt4Kqnz1AZaiKZ5+GICq0/1MH/mO/eAJHt/mHW1zjKBJd7kV26SrxddAhiw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0" + } + }, "System.Runtime.CompilerServices.Unsafe": { "type": "Transitive", "resolved": "6.0.0", @@ -244,25 +357,25 @@ }, "System.Text.Encodings.Web": { "type": "Transitive", - "resolved": "6.0.0", - "contentHash": "Vg8eB5Tawm1IFqj4TVK1czJX89rhFxJo9ELqc/Eiq0eXy13RK00eubyU6TJE6y+GQXjyV5gSfiewDUZjQgSE0w==", + "resolved": "7.0.0", + "contentHash": "OP6umVGxc0Z0MvZQBVigj4/U31Pw72ITihDWP9WiWDm+q5aoe0GaJivsfYGq53o6dxH7DcXWiCTl7+0o2CGdmg==", "dependencies": { "System.Buffers": "4.5.1", - "System.Memory": "4.5.4", + "System.Memory": "4.5.5", "System.Runtime.CompilerServices.Unsafe": "6.0.0" } }, "System.Text.Json": { "type": "Transitive", - "resolved": "6.0.0", - "contentHash": "zaJsHfESQvJ11vbXnNlkrR46IaMULk/gHxYsJphzSF+07kTjPHv+Oc14w6QEOfo3Q4hqLJgStUaYB9DBl0TmWg==", + "resolved": "7.0.3", + "contentHash": "AyjhwXN1zTFeIibHimfJn6eAsZ7rTBib79JQpzg8WAuR/HKDu9JGNHTuu3nbbXQ/bgI+U4z6HtZmCHNXB1QXrQ==", "dependencies": { - "Microsoft.Bcl.AsyncInterfaces": "6.0.0", + "Microsoft.Bcl.AsyncInterfaces": "7.0.0", "System.Buffers": "4.5.1", - "System.Memory": "4.5.4", + "System.Memory": "4.5.5", "System.Numerics.Vectors": "4.5.0", "System.Runtime.CompilerServices.Unsafe": "6.0.0", - "System.Text.Encodings.Web": "6.0.0", + "System.Text.Encodings.Web": "7.0.0", "System.Threading.Tasks.Extensions": "4.5.4" } }, @@ -299,7 +412,7 @@ "Microsoft.Extensions.DependencyInjection.Abstractions": "[6.0.0, )", "Microsoft.Extensions.Http": "[6.0.0, )", "RabbitMQ.Client": "[6.4.0, )", - "SecTester.Core": "[0.31.0, )", + "SecTester.Core": "[0.40.0, )", "System.Text.Json": "[6.0.0, )", "System.Threading.RateLimiting": "[7.0.0, )" } @@ -316,8 +429,10 @@ "type": "Project", "dependencies": { "Microsoft.Extensions.DependencyInjection.Abstractions": "[6.0.0, )", - "SecTester.Bus": "[0.31.0, )", - "SecTester.Core": "[0.31.0, )", + "SecTester.Bus": "[0.40.0, )", + "SecTester.Core": "[0.40.0, )", + "SocketIO.Serializer.MessagePack": "[3.1.1, )", + "SocketIOClient": "[3.1.1, )", "System.Linq.Async": "[6.0.1, )" } }, @@ -325,7 +440,7 @@ "type": "Project", "dependencies": { "Microsoft.Extensions.DependencyInjection.Abstractions": "[6.0.0, )", - "SecTester.Scan": "[0.31.0, )" + "SecTester.Scan": "[0.40.0, )" } }, "sectester.scan": { @@ -333,12 +448,12 @@ "dependencies": { "Macross.Json.Extensions": "[3.0.0, )", "Microsoft.Extensions.DependencyInjection.Abstractions": "[6.0.0, )", - "SecTester.Bus": "[0.31.0, )", - "SecTester.Core": "[0.31.0, )", + "SecTester.Bus": "[0.40.0, )", + "SecTester.Core": "[0.40.0, )", "System.Linq.Async": "[6.0.1, )", "System.Text.Json": "[6.0.0, )" } } } } -} +} \ No newline at end of file diff --git a/src/SecTester.Scan/packages.lock.json b/src/SecTester.Scan/packages.lock.json index 4c0a3d7..15f9d14 100644 --- a/src/SecTester.Scan/packages.lock.json +++ b/src/SecTester.Scan/packages.lock.json @@ -302,7 +302,7 @@ "Microsoft.Extensions.DependencyInjection.Abstractions": "[6.0.0, )", "Microsoft.Extensions.Http": "[6.0.0, )", "RabbitMQ.Client": "[6.4.0, )", - "SecTester.Core": "[0.29.0, )", + "SecTester.Core": "[0.40.0, )", "System.Text.Json": "[6.0.0, )", "System.Threading.RateLimiting": "[7.0.0, )" } diff --git a/test/SecTester.Bus.Tests/packages.lock.json b/test/SecTester.Bus.Tests/packages.lock.json index 253a644..a2f68df 100644 --- a/test/SecTester.Bus.Tests/packages.lock.json +++ b/test/SecTester.Bus.Tests/packages.lock.json @@ -1343,7 +1343,7 @@ "Microsoft.Extensions.DependencyInjection.Abstractions": "[6.0.0, )", "Microsoft.Extensions.Http": "[6.0.0, )", "RabbitMQ.Client": "[6.4.0, )", - "SecTester.Core": "[0.29.0, )", + "SecTester.Core": "[0.40.0, )", "System.Text.Json": "[6.0.0, )", "System.Threading.RateLimiting": "[7.0.0, )" } @@ -1361,8 +1361,8 @@ "dependencies": { "Macross.Json.Extensions": "[3.0.0, )", "Microsoft.Extensions.DependencyInjection.Abstractions": "[6.0.0, )", - "SecTester.Bus": "[0.29.0, )", - "SecTester.Core": "[0.29.0, )", + "SecTester.Bus": "[0.40.0, )", + "SecTester.Core": "[0.40.0, )", "System.Linq.Async": "[6.0.1, )", "System.Text.Json": "[6.0.0, )" } diff --git a/test/SecTester.Repeater.Tests/Bus/DefaultRepeaterBusFactoryTests.cs b/test/SecTester.Repeater.Tests/Bus/DefaultRepeaterBusFactoryTests.cs new file mode 100644 index 0000000..74af99d --- /dev/null +++ b/test/SecTester.Repeater.Tests/Bus/DefaultRepeaterBusFactoryTests.cs @@ -0,0 +1,49 @@ +namespace SecTester.Repeater.Tests.Bus; + +public class DefaultRepeaterBusFactoryTests : IDisposable +{ + private const string Id = "99138d92-69db-44cb-952a-1cd9ec031e20"; + private const string Hostname = "app.brightsec.com"; + private const string Token = "0zmcwpe.nexr.0vlon8mp7lvxzjuvgjy88olrhadhiukk"; + + private readonly ILoggerFactory _loggerFactory = Substitute.For(); + private readonly ITimerProvider _timerProvider = Substitute.For(); + + public void Dispose() + { + _timerProvider.ClearSubstitute(); + _loggerFactory.ClearSubstitute(); + GC.SuppressFinalize(this); + } + + [Fact] + public async Task Create_CreatesBus() + { + // arrange + Configuration config = new(Hostname, new Credentials(Token)); + DefaultRepeaterBusFactory sut = new(config, _timerProvider, _loggerFactory); + + // act + await using var bus = sut.Create(Id); + + // assert + bus.Should().BeAssignableTo(); + } + + [Fact] + public async Task Create_CredentialsNotDefined_ThrowsError() + { + // arrange + Configuration config = new(Hostname); + DefaultRepeaterBusFactory sut = new(config, _timerProvider, _loggerFactory); + + // act + var act = async () => + { + await using var _ = sut.Create(Id); + }; + + // assert + await act.Should().ThrowAsync(); + } +} diff --git a/test/SecTester.Repeater.Tests/Bus/DefaultRepeaterEventBusFactoryTests.cs b/test/SecTester.Repeater.Tests/Bus/DefaultRepeaterEventBusFactoryTests.cs deleted file mode 100644 index aecd664..0000000 --- a/test/SecTester.Repeater.Tests/Bus/DefaultRepeaterEventBusFactoryTests.cs +++ /dev/null @@ -1,53 +0,0 @@ -using SecTester.Bus.Dispatchers; - -namespace SecTester.Repeater.Tests.Bus; - -public class DefaultRepeaterEventBusFactoryTests : IDisposable -{ - private const string Id = "99138d92-69db-44cb-952a-1cd9ec031e20"; - private const string Hostname = "app.brightsec.com"; - private const string Token = "0zmcwpe.nexr.0vlon8mp7lvxzjuvgjy88olrhadhiukk"; - - private readonly IRmqEventBusFactory _eventBusFactory = Substitute.For(); - - public void Dispose() - { - _eventBusFactory.ClearSubstitute(); - GC.SuppressFinalize(this); - } - - [Fact] - public void Create_CreatesEventBus() - { - // arrange - Configuration config = new(Hostname, new Credentials(Token)); - DefaultRepeaterEventBusFactory sut = new(config, _eventBusFactory); - - // act - using var eventBus = sut.Create(Id); - - // assert - _eventBusFactory.Received() - .CreateEventBus(Arg.Is(x => - x.Username == "bot" && - x.Password == config.Credentials!.Token && - x.Url == config.Bus && - x.ClientQueue.Contains(Id) && - x.Exchange == "EventBus" && - x.AppQueue == "app")); - } - - [Fact] - public void Create_CredentialsNotDefined_ThrowsError() - { - // arrange - Configuration config = new(Hostname); - DefaultRepeaterEventBusFactory sut = new(config, _eventBusFactory); - - // act - var act = () => sut.Create(Id); - - // assert - act.Should().Throw(); - } -} diff --git a/test/SecTester.Repeater.Tests/Bus/RequestExecutingEventHandlerTests.cs b/test/SecTester.Repeater.Tests/Bus/RequestExecutingEventHandlerTests.cs deleted file mode 100644 index cc66427..0000000 --- a/test/SecTester.Repeater.Tests/Bus/RequestExecutingEventHandlerTests.cs +++ /dev/null @@ -1,58 +0,0 @@ -namespace SecTester.Repeater.Tests.Bus; - -public class RequestExecutingEventHandlerTests : IDisposable -{ - private readonly RequestRunnerResolver _resolver = Substitute.For(); - private readonly RequestExecutingEventListener _sut; - - public RequestExecutingEventHandlerTests() - { - _sut = new RequestExecutingEventListener(_resolver); - } - - public void Dispose() - { - _resolver.ClearSubstitute(); - GC.SuppressFinalize(this); - } - - [Fact] - public async Task Handle_RunRequestHavingCorrespondingRunner() - { - // arrange - var @event = new RequestExecutingEvent(new Uri("http://foo.bar")) - { - Protocol = Protocol.Http - }; - var reply = new RequestExecutingResult - { - Protocol = Protocol.Http, - StatusCode = 200, - Body = "text" - }; - _resolver(Protocol.Http)!.Run(@event).Returns(reply); - - // act - var result = await _sut.Handle(@event); - - // assert - result.Should().BeEquivalentTo(reply); - } - - [Fact] - public async Task Handle_NoRunnerFound_ThrowsError() - { - // arrange - var @event = new RequestExecutingEvent(new Uri("http://foo.bar")) - { - Protocol = Protocol.Http - }; - _resolver(Arg.Any()).ReturnsNull(); - - // act - var act = () => _sut.Handle(@event); - - // assert - await act.Should().ThrowAsync().WithMessage($"Unsupported protocol {Protocol.Http}"); - } -} diff --git a/test/SecTester.Repeater.Tests/DefaultRepeaterFactoryTests.cs b/test/SecTester.Repeater.Tests/DefaultRepeaterFactoryTests.cs index cb70543..f9cbce2 100644 --- a/test/SecTester.Repeater.Tests/DefaultRepeaterFactoryTests.cs +++ b/test/SecTester.Repeater.Tests/DefaultRepeaterFactoryTests.cs @@ -7,20 +7,22 @@ public class DefaultRepeaterFactoryTests : IDisposable private const string Hostname = "app.brightsec.com"; private readonly IServiceScopeFactory _serviceScopeFactory = Substitute.For(); - private readonly IRepeaterEventBusFactory _eventBusFactory = Substitute.For(); + private readonly IRepeaterBusFactory _busFactory = Substitute.For(); private readonly Configuration _configuration = new(Hostname); private readonly IRepeaters _repeaters = Substitute.For(); private readonly ILoggerFactory _loggerFactory = Substitute.For(); private readonly ITimerProvider _timerProvider = Substitute.For(); private readonly IAnsiCodeColorizer _ansiCodeColorizer = Substitute.For(); + private readonly RequestRunnerResolver _resolver = Substitute.For(); + private readonly DefaultRepeaterFactory _sut; public DefaultRepeaterFactoryTests() { // ADHOC: since GetRequiredService is part of extension we should explicitly mock an instance method _serviceScopeFactory.CreateAsyncScope().ServiceProvider.GetService(typeof(ITimerProvider)).Returns(_timerProvider); - _sut = new DefaultRepeaterFactory(_serviceScopeFactory, _repeaters, _eventBusFactory, _configuration, _loggerFactory, _ansiCodeColorizer); + _sut = new DefaultRepeaterFactory(_repeaters, _busFactory, _configuration, _loggerFactory, _ansiCodeColorizer, _resolver); } public void Dispose() @@ -28,9 +30,10 @@ public void Dispose() _ansiCodeColorizer.ClearSubstitute(); _timerProvider.ClearSubstitute(); _serviceScopeFactory.ClearSubstitute(); - _eventBusFactory.ClearSubstitute(); + _busFactory.ClearSubstitute(); _repeaters.ClearSubstitute(); _loggerFactory.ClearSubstitute(); + _resolver.ClearSubstitute(); GC.SuppressFinalize(this); } diff --git a/test/SecTester.Repeater.Tests/RepeaterTests.cs b/test/SecTester.Repeater.Tests/RepeaterTests.cs index fdf8a3d..8c1b13b 100644 --- a/test/SecTester.Repeater.Tests/RepeaterTests.cs +++ b/test/SecTester.Repeater.Tests/RepeaterTests.cs @@ -5,42 +5,18 @@ public class RepeaterTests : IDisposable, IAsyncDisposable private const string Version = "42.0.1"; private const string Id = "99138d92-69db-44cb-952a-1cd9ec031e20"; - public static readonly IEnumerable RegistrationErrors = new List - { - new object[] - { - new RegisterRepeaterResult(new RegisterRepeaterPayload(Error: RepeaterRegisteringError.Busy)), $"There is an already running Repeater with ID {Id}" - }, - new object[] - { - new RegisterRepeaterResult(new RegisterRepeaterPayload(Error: RepeaterRegisteringError.NotActive)), "The current Repeater is not active" - }, - new object[] - { - new RegisterRepeaterResult(new RegisterRepeaterPayload(Error: RepeaterRegisteringError.NotFound)), "Unauthorized access" - }, - new object[] - { - new RegisterRepeaterResult(new RegisterRepeaterPayload(Error: RepeaterRegisteringError.RequiresToBeUpdated)), - "The current running version is no longer supported" - }, - new object[] - { - new RegisterRepeaterResult(new RegisterRepeaterPayload(Error: (RepeaterRegisteringError)(-100))), "Something went wrong. Unknown error." - } - }; - - private readonly IEventBus _eventBus = Substitute.For(); + private readonly IRepeaterBus _bus = Substitute.For(); private readonly MockLogger _logger = Substitute.For>(); - private readonly Repeater _sut; private readonly ITimerProvider _timerProvider = Substitute.For(); private readonly IAnsiCodeColorizer _ansiCodeColorizer = Substitute.For(); + private readonly RequestRunnerResolver _resolver = Substitute.For(); + + private readonly Repeater _sut; public RepeaterTests() { var version = new Version(Version); - _eventBus.Execute(Arg.Any()).Returns(new RegisterRepeaterResult(new RegisterRepeaterPayload(Version))); - _sut = new Repeater(Id, _eventBus, version, _logger, _timerProvider, _ansiCodeColorizer); + _sut = new Repeater(Id, _bus, version, _logger, _ansiCodeColorizer, _resolver); } public async ValueTask DisposeAsync() @@ -55,20 +31,21 @@ public void Dispose() { _ansiCodeColorizer.ClearSubstitute(); _logger.ClearSubstitute(); - _eventBus.ClearSubstitute(); + _bus.ClearSubstitute(); _timerProvider.ClearSubstitute(); + _resolver.ClearSubstitute(); + GC.SuppressFinalize(this); } [Fact] - public async Task Start_RegistersInApp() + public async Task Start_DeploysItself() { // act await _sut.Start(); // assert - await _eventBus.Received().Execute(Arg.Any()); - await _eventBus.Received().Publish(Arg.Is(x => x.Status == RepeaterStatus.Connected && x.RepeaterId == Id)); + await _bus.Received().Deploy(Id, Arg.Any(), Arg.Any()); } [Fact] @@ -85,33 +62,20 @@ public async Task Start_OperationCancelled_ReThrowsError() await act.Should().ThrowAsync(); } - [Fact] - public async Task Start_RegistrationFailed_RegistersInApp() - { - // arrange - _eventBus.Execute(Arg.Any()).ReturnsNull(); - - // act - var act = () => _sut.Start(); - - // assert - await act.Should().ThrowAsync().WithMessage("Error registering repeater."); - } - - [Fact] - public async Task Start_SendsPingPeriodically() - { - // arrange - var elapsedEventArgs = EventArgs.Empty as ElapsedEventArgs; - - // act - await _sut.Start(); - - // assert - _timerProvider.Interval.Should().BeGreaterOrEqualTo(10_000); - _timerProvider.Elapsed += Raise.Event(new object(), elapsedEventArgs); - await _eventBus.Received(2).Publish(Arg.Is(x => x.Status == RepeaterStatus.Connected && x.RepeaterId == Id)); - } + // [Fact] + // public async Task Start_SendsPingPeriodically() + // { + // // arrange + // var elapsedEventArgs = EventArgs.Empty as ElapsedEventArgs; + // + // // act + // await _sut.Start(); + // + // // assert + // _timerProvider.Interval.Should().BeGreaterOrEqualTo(10_000); + // _timerProvider.Elapsed += Raise.Event(new object(), elapsedEventArgs); + // await _bus.Received(2).Publish(Arg.Is(x => x.Status == RepeaterStatus.Connected && x.RepeaterId == Id)); + // } [Fact] public async Task Start_SetsStatusToRunningJustAfterCall() @@ -136,47 +100,20 @@ public async Task Start_RepeaterIsStarting_ThrowsError() await act.Should().ThrowAsync().WithMessage("Repeater is already active."); } - [Fact] - public async Task Start_AbortedByError_Restarts() - { - // arrange - _eventBus.Execute(Arg.Any()).Returns(null, new RegisterRepeaterResult(new RegisterRepeaterPayload(Version))); - - // act - var act = () => _sut.Start(); - - // assert - await act.Should().ThrowAsync(); - await act.Should().NotThrowAsync(); - } - - [Theory] - [MemberData(nameof(RegistrationErrors))] - public async Task Start_ErrorWhileRegistration_ThrowsError(RegisterRepeaterResult input, string expected) - { - // arrange - _eventBus.Execute(Arg.Any()).Returns(input); - - // act - var act = () => _sut.Start(); - - // assert - await act.Should().ThrowAsync().WithMessage($"*{expected}*"); - } - - [Fact] - public async Task Start_NewVersionIsAvailable_ShowsWarning() - { - // arrange - var newVersion = new Regex(@"(\d+)").Replace(Version, x => $"{int.Parse(x.Groups[0].Value) + 1}"); - _eventBus.Execute(Arg.Any()).Returns(new RegisterRepeaterResult(new RegisterRepeaterPayload(newVersion))); - - // act - await _sut.Start(); - - // assert - _logger.Received().Log(LogLevel.Warning, Arg.Is(s => s.Contains($"A new Repeater version ({newVersion}) is available"))); - } + // [Fact] + // public async Task Start_NewVersionIsAvailable_ShowsWarning() + // { + // // arrange + // var newVersion = new Regex(@"(\d+)").Replace(Version, x => $"{int.Parse(x.Groups[0].Value) + 1}"); + // _bus.Execute(Arg.Any()).Returns(new RegisterRepeaterResult(new RegisterRepeaterPayload(newVersion))); + // _bus.Deploy(RepeaterId, new Runtime(_version.ToString()), cancellationToken).ConfigureAwait(false); + // + // // act + // await _sut.Start(); + // + // // assert + // _logger.Received().Log(LogLevel.Warning, Arg.Is(s => s.Contains($"A new Repeater version ({newVersion}) is available"))); + // } [Fact] public async Task Stop_RunningRepeater_Stops() @@ -188,7 +125,7 @@ public async Task Stop_RunningRepeater_Stops() await _sut.Stop(); // assert - await _eventBus.Received().Publish(Arg.Is(x => x.Status == RepeaterStatus.Disconnected && x.RepeaterId == Id)); + await _bus.Received().DisposeAsync(); } [Fact] @@ -207,9 +144,6 @@ public async Task Stop_RunningRepeater_EntersIntoOff() [Fact] public async Task Stop_RepeaterIsOff_DoesNothing() { - // arrange - _eventBus.Execute(Arg.Any()).ReturnsNull(); - // act await _sut.Stop(); @@ -231,21 +165,21 @@ public async Task Stop_RepeaterIsOff_IgnoresSecondCall() _sut.Status.Should().Be(RunningStatus.Off); } - [Fact] - public async Task Stop_StopsSendingPing() - { - // arrange - await _sut.Start(); - - // act - await _sut.Stop(); - - // assert - _timerProvider.Received().Stop(); - } + // [Fact] + // public async Task Stop_StopsSendingPing() + // { + // // arrange + // await _sut.Start(); + // + // // act + // await _sut.Stop(); + // + // // assert + // _timerProvider.Received().Stop(); + // } [Fact] - public async Task Stop_OperationCancelled_ReThrowsError() + public async Task Stop_OperationCancelled_ThrowsError() { // arrange using var cancellationTokenSource = new CancellationTokenSource(); @@ -268,6 +202,46 @@ public async Task DisposeAsync_StopsRepeater() await _sut.DisposeAsync(); // assert - await _eventBus.Received().Publish(Arg.Is(x => x.Status == RepeaterStatus.Disconnected && x.RepeaterId == Id)); - } + await _bus.Received().DisposeAsync(); + } + + // [Fact] + // public async Task Handle_RunRequestHavingCorrespondingRunner() + // { + // // arrange + // var @event = new IncomingRequest(new Uri("http://foo.bar")) + // { + // Protocol = Protocol.Http + // }; + // var reply = new OutgoingResponse + // { + // Protocol = Protocol.Http, + // StatusCode = 200, + // Body = "text" + // }; + // _resolver(Protocol.Http)!.Run(@event).Returns(reply); + // + // // act + // var result = await _sut.Handle(@event); + // + // // assert + // result.Should().BeEquivalentTo(reply); + // } + // + // [Fact] + // public async Task Handle_NoRunnerFound_ThrowsError() + // { + // // arrange + // var @event = new IncomingRequest(new Uri("http://foo.bar")) + // { + // Protocol = Protocol.Http + // }; + // _resolver(Arg.Any()).ReturnsNull(); + // + // // act + // var act = () => _sut.Handle(@event); + // + // // assert + // await act.Should().ThrowAsync().WithMessage($"Unsupported protocol {Protocol.Http}"); + // } } diff --git a/test/SecTester.Repeater.Tests/Runners/HttpRequestRunnerTests.cs b/test/SecTester.Repeater.Tests/Runners/HttpRequestRunnerTests.cs index 6eee2c7..4061f85 100644 --- a/test/SecTester.Repeater.Tests/Runners/HttpRequestRunnerTests.cs +++ b/test/SecTester.Repeater.Tests/Runners/HttpRequestRunnerTests.cs @@ -51,7 +51,7 @@ public async Task Run_ReturnsResult_WhenRequestIsSuccessful() HeaderFieldValue }) }; - var request = new RequestExecutingEvent(Uri) + var request = new IncomingRequest(Uri) { Method = HttpMethod.Patch, Body = JsonContent, @@ -84,7 +84,7 @@ public async Task Run_ReturnsResultWithDecodedBody() var sut = CreateSut(); var encoding = Encoding.GetEncoding("utf-16"); var expectedByteLength = Buffer.ByteLength(encoding.GetBytes(HtmlBody)); - var request = new RequestExecutingEvent(Uri); + var request = new IncomingRequest(Uri); var content = new StringContent(HtmlBody, encoding, HtmlContentType); _mockHttp.Expect(Url).Respond(HttpStatusCode.OK, content); @@ -118,7 +118,7 @@ public async Task Run_ReturnsResultWithError_WhenRequestTimesOut() { Timeout = TimeSpan.Zero }); - var request = new RequestExecutingEvent(Uri); + var request = new IncomingRequest(Uri); _mockHttp.Expect(Url) .Respond(async () => { @@ -146,7 +146,7 @@ public async Task Run_MaxContentLengthIsLessThan0_SkipsTruncating() { MaxContentLength = -1 }); - var request = new RequestExecutingEvent(Uri); + var request = new IncomingRequest(Uri); var body = string.Concat(Enumerable.Repeat("x", 5)); _mockHttp.Expect(Url).Respond(HttpStatusCode.OK, CustomContentType, body); @@ -165,7 +165,7 @@ public async Task Run_NoContentStatusReceived_SkipsTruncating() { // arrange var sut = CreateSut(); - var request = new RequestExecutingEvent(Uri); + var request = new IncomingRequest(Uri); _mockHttp.Expect(Url).Respond(HttpStatusCode.NoContent); // act @@ -184,7 +184,7 @@ public async Task Run_HeadMethodUsed_SkipsTruncating() { // arrange var sut = CreateSut(); - var request = new RequestExecutingEvent(Uri) + var request = new IncomingRequest(Uri) { Method = HttpMethod.Head }; @@ -206,7 +206,7 @@ public async Task Run_AllowedMimeReceived_SkipsTruncating() { // arrange var sut = CreateSut(); - var request = new RequestExecutingEvent(Uri); + var request = new IncomingRequest(Uri); _mockHttp.Expect(Url).Respond(HttpStatusCode.OK, JsonContentType, JsonContent); // act @@ -240,7 +240,7 @@ public async Task Run_NotAllowedMimeReceived_TruncatesBody() $"{options.MaxContentLength}" }) }; - var request = new RequestExecutingEvent(Uri); + var request = new IncomingRequest(Uri); var body = string.Concat(Enumerable.Repeat("x", 5)); _mockHttp.Expect(Url).Respond(HttpStatusCode.OK, CustomContentType, body); @@ -261,7 +261,7 @@ public async Task Run_HttpStatusException_ReturnsResponse() { // arrange var sut = CreateSut(); - var request = new RequestExecutingEvent(Uri); + var request = new IncomingRequest(Uri); _mockHttp.Expect(Url).Respond(HttpStatusCode.ServiceUnavailable, JsonContentType, JsonContent); // act @@ -280,7 +280,7 @@ public async Task Run_TcpException_ReturnsResponse() { // arrange var sut = CreateSut(); - var request = new RequestExecutingEvent(Uri); + var request = new IncomingRequest(Uri); _mockHttp.Expect(Url).Throw(new SocketException((int)SocketError.ConnectionRefused)); // act @@ -292,7 +292,7 @@ public async Task Run_TcpException_ReturnsResponse() ErrorCode = "ConnectionRefused" }, options => options.Using(ctx => ctx.Subject.Should().BeOfType()) - .When(info => info.Path.EndsWith(nameof(RequestExecutingResult.Message)))); + .When(info => info.Path.EndsWith(nameof(OutgoingResponse.Message)))); } [Fact] @@ -307,7 +307,7 @@ public async Task Run_BypassesStrictHttpValidation() InvalidHostHeaderValue }) }; - var request = new RequestExecutingEvent(Uri) + var request = new IncomingRequest(Uri) { Headers = headers }; @@ -334,7 +334,7 @@ public async Task Run_AcceptsContentHeaders() JsonContentType }) }; - var request = new RequestExecutingEvent(Uri) + var request = new IncomingRequest(Uri) { Method = HttpMethod.Post, Headers = headers, diff --git a/test/SecTester.Repeater.Tests/packages.lock.json b/test/SecTester.Repeater.Tests/packages.lock.json index b95d060..d7051cc 100644 --- a/test/SecTester.Repeater.Tests/packages.lock.json +++ b/test/SecTester.Repeater.Tests/packages.lock.json @@ -99,6 +99,21 @@ "resolved": "3.0.0", "contentHash": "AkNshs6dopj8FXsmkkJxvLivN2SyDJQDbjcds5lo9+Y6L4zpcoXdmzXQ3VVN+AIWQr0CTD5A7vkuHGAr2aypZg==" }, + "MessagePack": { + "type": "Transitive", + "resolved": "2.5.124", + "contentHash": "jxJPIkCnKwZcg9qtN1WoR99nlcJl/y/HYOTQLxnyXzR4iE5xhZviCPSKXLe08fcF9Tk4hP7mm+mVVdyUfh2ALw==", + "dependencies": { + "MessagePack.Annotations": "2.5.124", + "Microsoft.NET.StringTools": "17.6.3", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "MessagePack.Annotations": { + "type": "Transitive", + "resolved": "2.5.124", + "contentHash": "YTWbSjVlMhe6WaEQ953rrNagRzQxDrp9mCB3W2Yr1TOITlaEv/ZMFvqZSabSs09Gy86Kq7BmvcxKTodv/YNDQA==" + }, "Microsoft.AspNetCore.TestHost": { "type": "Transitive", "resolved": "6.0.11", @@ -417,6 +432,15 @@ "System.Runtime.CompilerServices.Unsafe": "6.0.0" } }, + "Microsoft.NET.StringTools": { + "type": "Transitive", + "resolved": "17.6.3", + "contentHash": "N0ZIanl1QCgvUumEL1laasU0a7sOE5ZwLZVTn0pAePnfhq8P7SvTjF8Axq+CnavuQkmdQpGNXQ1efZtu5kDFbA==", + "dependencies": { + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, "Microsoft.NETCore.Platforms": { "type": "Transitive", "resolved": "1.1.0", @@ -656,6 +680,49 @@ "resolved": "4.3.0", "contentHash": "VB5cn/7OzUfzdnC8tqAIMQciVLiq2epm2NrAm1E9OjNRyG4lVhfR61SMcLizejzQP8R8Uf/0l5qOIbUEi+RdEg==" }, + "SocketIO.Core": { + "type": "Transitive", + "resolved": "3.1.1", + "contentHash": "L5GSyODDjlub5YdDxfsRtA9uxBNw1Hs/egEMhdOGFyD0c63VmvWQ1A4Gfc4GYKYInz1muP4C8QNblXErnUYDqA==" + }, + "SocketIO.Serializer.Core": { + "type": "Transitive", + "resolved": "3.1.1", + "contentHash": "aFanlt2GOGEy7GTGLyh8f8SwhtmQwoPOHTAYCQ0brjg05Nb3F38sk4hYogpII5imyZ7w0spqwNHwpl7FZ49HOA==", + "dependencies": { + "SocketIO.Core": "3.1.1" + } + }, + "SocketIO.Serializer.MessagePack": { + "type": "Transitive", + "resolved": "3.1.1", + "contentHash": "lOAZs6AUCDhfMFa4Vu40LeeK/9fP+iMUerI3qzmToDaSa+A2/YQ7D0nvYa1atwTvzvhDZklBKNV5dIzQWWwPJg==", + "dependencies": { + "MessagePack": "2.5.124", + "SocketIO.Core": "3.1.1", + "SocketIO.Serializer.Core": "3.1.1" + } + }, + "SocketIO.Serializer.SystemTextJson": { + "type": "Transitive", + "resolved": "3.1.1", + "contentHash": "1PKQ+hOAJ4l3ZXlrVgiB3uNY3kLhjzYjnxk/97V6npJrNmhq09Di2EQSpGweQMu6KPbOxjZ7eYVARkGTWIUsjg==", + "dependencies": { + "SocketIO.Core": "3.1.1", + "SocketIO.Serializer.Core": "3.1.1", + "System.Text.Json": "7.0.3" + } + }, + "SocketIOClient": { + "type": "Transitive", + "resolved": "3.1.1", + "contentHash": "g8Lauia1Cj5DBXeC9j6vDSJeQEboGmXsnduW06VOBMe+UgqCrenxszYXJg19rAjwO10XRWQorOuU1XNMfYo8Xg==", + "dependencies": { + "SocketIO.Serializer.Core": "3.1.1", + "SocketIO.Serializer.SystemTextJson": "3.1.1", + "System.Collections": "4.3.0" + } + }, "System.AppContext": { "type": "Transitive", "resolved": "4.3.0", @@ -939,8 +1006,8 @@ }, "System.Memory": { "type": "Transitive", - "resolved": "4.5.4", - "contentHash": "1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw==" + "resolved": "4.5.5", + "contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==" }, "System.Net.Http": { "type": "Transitive", @@ -1356,19 +1423,19 @@ }, "System.Text.Encodings.Web": { "type": "Transitive", - "resolved": "6.0.0", - "contentHash": "Vg8eB5Tawm1IFqj4TVK1czJX89rhFxJo9ELqc/Eiq0eXy13RK00eubyU6TJE6y+GQXjyV5gSfiewDUZjQgSE0w==", + "resolved": "7.0.0", + "contentHash": "OP6umVGxc0Z0MvZQBVigj4/U31Pw72ITihDWP9WiWDm+q5aoe0GaJivsfYGq53o6dxH7DcXWiCTl7+0o2CGdmg==", "dependencies": { "System.Runtime.CompilerServices.Unsafe": "6.0.0" } }, "System.Text.Json": { "type": "Transitive", - "resolved": "6.0.0", - "contentHash": "zaJsHfESQvJ11vbXnNlkrR46IaMULk/gHxYsJphzSF+07kTjPHv+Oc14w6QEOfo3Q4hqLJgStUaYB9DBl0TmWg==", + "resolved": "7.0.3", + "contentHash": "AyjhwXN1zTFeIibHimfJn6eAsZ7rTBib79JQpzg8WAuR/HKDu9JGNHTuu3nbbXQ/bgI+U4z6HtZmCHNXB1QXrQ==", "dependencies": { "System.Runtime.CompilerServices.Unsafe": "6.0.0", - "System.Text.Encodings.Web": "6.0.0" + "System.Text.Encodings.Web": "7.0.0" } }, "System.Text.RegularExpressions": { @@ -1522,7 +1589,7 @@ "Microsoft.Extensions.DependencyInjection.Abstractions": "[6.0.0, )", "Microsoft.Extensions.Http": "[6.0.0, )", "RabbitMQ.Client": "[6.4.0, )", - "SecTester.Core": "[0.26.0, )", + "SecTester.Core": "[0.40.0, )", "System.Text.Json": "[6.0.0, )", "System.Threading.RateLimiting": "[7.0.0, )" } @@ -1539,8 +1606,10 @@ "type": "Project", "dependencies": { "Microsoft.Extensions.DependencyInjection.Abstractions": "[6.0.0, )", - "SecTester.Bus": "[0.26.0, )", - "SecTester.Core": "[0.26.0, )", + "SecTester.Bus": "[0.40.0, )", + "SecTester.Core": "[0.40.0, )", + "SocketIO.Serializer.MessagePack": "[3.1.1, )", + "SocketIOClient": "[3.1.1, )", "System.Linq.Async": "[6.0.1, )" } } diff --git a/test/SecTester.Reporter.Tests/packages.lock.json b/test/SecTester.Reporter.Tests/packages.lock.json index 5354e99..02830eb 100644 --- a/test/SecTester.Reporter.Tests/packages.lock.json +++ b/test/SecTester.Reporter.Tests/packages.lock.json @@ -1337,7 +1337,7 @@ "Microsoft.Extensions.DependencyInjection.Abstractions": "[6.0.0, )", "Microsoft.Extensions.Http": "[6.0.0, )", "RabbitMQ.Client": "[6.4.0, )", - "SecTester.Core": "[0.29.2, )", + "SecTester.Core": "[0.40.0, )", "System.Text.Json": "[6.0.0, )", "System.Threading.RateLimiting": "[7.0.0, )" } @@ -1354,7 +1354,7 @@ "type": "Project", "dependencies": { "Microsoft.Extensions.DependencyInjection.Abstractions": "[6.0.0, )", - "SecTester.Scan": "[0.29.2, )" + "SecTester.Scan": "[0.40.0, )" } }, "sectester.scan": { @@ -1362,8 +1362,8 @@ "dependencies": { "Macross.Json.Extensions": "[3.0.0, )", "Microsoft.Extensions.DependencyInjection.Abstractions": "[6.0.0, )", - "SecTester.Bus": "[0.29.2, )", - "SecTester.Core": "[0.29.2, )", + "SecTester.Bus": "[0.40.0, )", + "SecTester.Core": "[0.40.0, )", "System.Linq.Async": "[6.0.1, )", "System.Text.Json": "[6.0.0, )" } diff --git a/test/SecTester.Runner.Tests/packages.lock.json b/test/SecTester.Runner.Tests/packages.lock.json index d21bb0a..5ac24be 100644 --- a/test/SecTester.Runner.Tests/packages.lock.json +++ b/test/SecTester.Runner.Tests/packages.lock.json @@ -82,6 +82,21 @@ "resolved": "3.0.0", "contentHash": "AkNshs6dopj8FXsmkkJxvLivN2SyDJQDbjcds5lo9+Y6L4zpcoXdmzXQ3VVN+AIWQr0CTD5A7vkuHGAr2aypZg==" }, + "MessagePack": { + "type": "Transitive", + "resolved": "2.5.124", + "contentHash": "jxJPIkCnKwZcg9qtN1WoR99nlcJl/y/HYOTQLxnyXzR4iE5xhZviCPSKXLe08fcF9Tk4hP7mm+mVVdyUfh2ALw==", + "dependencies": { + "MessagePack.Annotations": "2.5.124", + "Microsoft.NET.StringTools": "17.6.3", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "MessagePack.Annotations": { + "type": "Transitive", + "resolved": "2.5.124", + "contentHash": "YTWbSjVlMhe6WaEQ953rrNagRzQxDrp9mCB3W2Yr1TOITlaEv/ZMFvqZSabSs09Gy86Kq7BmvcxKTodv/YNDQA==" + }, "Microsoft.Bcl.AsyncInterfaces": { "type": "Transitive", "resolved": "7.0.0", @@ -230,6 +245,15 @@ "System.Runtime.CompilerServices.Unsafe": "6.0.0" } }, + "Microsoft.NET.StringTools": { + "type": "Transitive", + "resolved": "17.6.3", + "contentHash": "N0ZIanl1QCgvUumEL1laasU0a7sOE5ZwLZVTn0pAePnfhq8P7SvTjF8Axq+CnavuQkmdQpGNXQ1efZtu5kDFbA==", + "dependencies": { + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, "Microsoft.NETCore.Platforms": { "type": "Transitive", "resolved": "1.1.0", @@ -469,6 +493,49 @@ "resolved": "4.3.0", "contentHash": "VB5cn/7OzUfzdnC8tqAIMQciVLiq2epm2NrAm1E9OjNRyG4lVhfR61SMcLizejzQP8R8Uf/0l5qOIbUEi+RdEg==" }, + "SocketIO.Core": { + "type": "Transitive", + "resolved": "3.1.1", + "contentHash": "L5GSyODDjlub5YdDxfsRtA9uxBNw1Hs/egEMhdOGFyD0c63VmvWQ1A4Gfc4GYKYInz1muP4C8QNblXErnUYDqA==" + }, + "SocketIO.Serializer.Core": { + "type": "Transitive", + "resolved": "3.1.1", + "contentHash": "aFanlt2GOGEy7GTGLyh8f8SwhtmQwoPOHTAYCQ0brjg05Nb3F38sk4hYogpII5imyZ7w0spqwNHwpl7FZ49HOA==", + "dependencies": { + "SocketIO.Core": "3.1.1" + } + }, + "SocketIO.Serializer.MessagePack": { + "type": "Transitive", + "resolved": "3.1.1", + "contentHash": "lOAZs6AUCDhfMFa4Vu40LeeK/9fP+iMUerI3qzmToDaSa+A2/YQ7D0nvYa1atwTvzvhDZklBKNV5dIzQWWwPJg==", + "dependencies": { + "MessagePack": "2.5.124", + "SocketIO.Core": "3.1.1", + "SocketIO.Serializer.Core": "3.1.1" + } + }, + "SocketIO.Serializer.SystemTextJson": { + "type": "Transitive", + "resolved": "3.1.1", + "contentHash": "1PKQ+hOAJ4l3ZXlrVgiB3uNY3kLhjzYjnxk/97V6npJrNmhq09Di2EQSpGweQMu6KPbOxjZ7eYVARkGTWIUsjg==", + "dependencies": { + "SocketIO.Core": "3.1.1", + "SocketIO.Serializer.Core": "3.1.1", + "System.Text.Json": "7.0.3" + } + }, + "SocketIOClient": { + "type": "Transitive", + "resolved": "3.1.1", + "contentHash": "g8Lauia1Cj5DBXeC9j6vDSJeQEboGmXsnduW06VOBMe+UgqCrenxszYXJg19rAjwO10XRWQorOuU1XNMfYo8Xg==", + "dependencies": { + "SocketIO.Serializer.Core": "3.1.1", + "SocketIO.Serializer.SystemTextJson": "3.1.1", + "System.Collections": "4.3.0" + } + }, "System.AppContext": { "type": "Transitive", "resolved": "4.3.0", @@ -754,8 +821,8 @@ }, "System.Memory": { "type": "Transitive", - "resolved": "4.5.4", - "contentHash": "1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw==" + "resolved": "4.5.5", + "contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==" }, "System.Net.Http": { "type": "Transitive", @@ -1171,19 +1238,19 @@ }, "System.Text.Encodings.Web": { "type": "Transitive", - "resolved": "6.0.0", - "contentHash": "Vg8eB5Tawm1IFqj4TVK1czJX89rhFxJo9ELqc/Eiq0eXy13RK00eubyU6TJE6y+GQXjyV5gSfiewDUZjQgSE0w==", + "resolved": "7.0.0", + "contentHash": "OP6umVGxc0Z0MvZQBVigj4/U31Pw72ITihDWP9WiWDm+q5aoe0GaJivsfYGq53o6dxH7DcXWiCTl7+0o2CGdmg==", "dependencies": { "System.Runtime.CompilerServices.Unsafe": "6.0.0" } }, "System.Text.Json": { "type": "Transitive", - "resolved": "6.0.0", - "contentHash": "zaJsHfESQvJ11vbXnNlkrR46IaMULk/gHxYsJphzSF+07kTjPHv+Oc14w6QEOfo3Q4hqLJgStUaYB9DBl0TmWg==", + "resolved": "7.0.3", + "contentHash": "AyjhwXN1zTFeIibHimfJn6eAsZ7rTBib79JQpzg8WAuR/HKDu9JGNHTuu3nbbXQ/bgI+U4z6HtZmCHNXB1QXrQ==", "dependencies": { "System.Runtime.CompilerServices.Unsafe": "6.0.0", - "System.Text.Encodings.Web": "6.0.0" + "System.Text.Encodings.Web": "7.0.0" } }, "System.Text.RegularExpressions": { @@ -1337,7 +1404,7 @@ "Microsoft.Extensions.DependencyInjection.Abstractions": "[6.0.0, )", "Microsoft.Extensions.Http": "[6.0.0, )", "RabbitMQ.Client": "[6.4.0, )", - "SecTester.Core": "[0.31.0, )", + "SecTester.Core": "[0.40.0, )", "System.Text.Json": "[6.0.0, )", "System.Threading.RateLimiting": "[7.0.0, )" } @@ -1354,8 +1421,10 @@ "type": "Project", "dependencies": { "Microsoft.Extensions.DependencyInjection.Abstractions": "[6.0.0, )", - "SecTester.Bus": "[0.31.0, )", - "SecTester.Core": "[0.31.0, )", + "SecTester.Bus": "[0.40.0, )", + "SecTester.Core": "[0.40.0, )", + "SocketIO.Serializer.MessagePack": "[3.1.1, )", + "SocketIOClient": "[3.1.1, )", "System.Linq.Async": "[6.0.1, )" } }, @@ -1363,16 +1432,16 @@ "type": "Project", "dependencies": { "Microsoft.Extensions.DependencyInjection.Abstractions": "[6.0.0, )", - "SecTester.Scan": "[0.31.0, )" + "SecTester.Scan": "[0.40.0, )" } }, "sectester.runner": { "type": "Project", "dependencies": { "Microsoft.Extensions.DependencyInjection.Abstractions": "[6.0.0, )", - "SecTester.Repeater": "[0.31.0, )", - "SecTester.Reporter": "[0.31.0, )", - "SecTester.Scan": "[0.31.0, )" + "SecTester.Repeater": "[0.40.0, )", + "SecTester.Reporter": "[0.40.0, )", + "SecTester.Scan": "[0.40.0, )" } }, "sectester.scan": { @@ -1380,12 +1449,12 @@ "dependencies": { "Macross.Json.Extensions": "[3.0.0, )", "Microsoft.Extensions.DependencyInjection.Abstractions": "[6.0.0, )", - "SecTester.Bus": "[0.31.0, )", - "SecTester.Core": "[0.31.0, )", + "SecTester.Bus": "[0.40.0, )", + "SecTester.Core": "[0.40.0, )", "System.Linq.Async": "[6.0.1, )", "System.Text.Json": "[6.0.0, )" } } } } -} +} \ No newline at end of file diff --git a/test/SecTester.Scan.Tests/packages.lock.json b/test/SecTester.Scan.Tests/packages.lock.json index 40e17f6..5ef1f12 100644 --- a/test/SecTester.Scan.Tests/packages.lock.json +++ b/test/SecTester.Scan.Tests/packages.lock.json @@ -1339,7 +1339,7 @@ "Microsoft.Extensions.DependencyInjection.Abstractions": "[6.0.0, )", "Microsoft.Extensions.Http": "[6.0.0, )", "RabbitMQ.Client": "[6.4.0, )", - "SecTester.Core": "[0.29.0, )", + "SecTester.Core": "[0.40.0, )", "System.Text.Json": "[6.0.0, )", "System.Threading.RateLimiting": "[7.0.0, )" } @@ -1357,8 +1357,8 @@ "dependencies": { "Macross.Json.Extensions": "[3.0.0, )", "Microsoft.Extensions.DependencyInjection.Abstractions": "[6.0.0, )", - "SecTester.Bus": "[0.29.0, )", - "SecTester.Core": "[0.29.0, )", + "SecTester.Bus": "[0.40.0, )", + "SecTester.Core": "[0.40.0, )", "System.Linq.Async": "[6.0.1, )", "System.Text.Json": "[6.0.0, )" }