2026-09-11 22:02:46 +00:00
|
|
|
using System.Net;
|
|
|
|
|
using System.Net.Sockets;
|
|
|
|
|
using w4c_workflows.Services.Security;
|
2026-09-13 16:28:47 +00:00
|
|
|
using w4c_workflows.Services.Nodes;
|
2026-09-11 22:02:46 +00:00
|
|
|
|
|
|
|
|
namespace w4c_workflows.Tests;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Deterministic <see cref="IHostAddressResolver"/> for egress tests: returns a
|
|
|
|
|
/// fixed address set per host and records every query, so tests never touch DNS.
|
|
|
|
|
/// </summary>
|
|
|
|
|
internal sealed class StubHostAddressResolver : IHostAddressResolver
|
|
|
|
|
{
|
|
|
|
|
private readonly Func<string, IReadOnlyList<IPAddress>> _resolve;
|
|
|
|
|
|
|
|
|
|
public StubHostAddressResolver(Func<string, IReadOnlyList<IPAddress>> resolve) => _resolve = resolve;
|
|
|
|
|
|
|
|
|
|
public List<string> Queries { get; } = new();
|
|
|
|
|
|
|
|
|
|
public Task<IReadOnlyList<IPAddress>> ResolveAsync(string host, CancellationToken ct)
|
|
|
|
|
{
|
|
|
|
|
Queries.Add(host);
|
|
|
|
|
return Task.FromResult(_resolve(host));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static StubHostAddressResolver Returning(params string[] addresses)
|
|
|
|
|
=> new(_ => addresses.Select(IPAddress.Parse).ToArray());
|
|
|
|
|
|
|
|
|
|
public static StubHostAddressResolver Failing()
|
|
|
|
|
=> new(_ => throw new SocketException((int)SocketError.HostNotFound));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal static class EgressTestData
|
|
|
|
|
{
|
|
|
|
|
/// <summary>A routable public address used as the default stub answer.</summary>
|
|
|
|
|
public const string PublicAddress = "93.184.216.34";
|
|
|
|
|
|
|
|
|
|
public static EgressPolicy Policy(Action<EgressPolicyOptions>? configure = null)
|
|
|
|
|
{
|
|
|
|
|
var options = new EgressPolicyOptions();
|
|
|
|
|
configure?.Invoke(options);
|
|
|
|
|
return new EgressPolicy(options);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static EgressGuard Guard(
|
|
|
|
|
EgressPolicy? policy = null,
|
|
|
|
|
IHostAddressResolver? resolver = null)
|
|
|
|
|
=> new(policy ?? Policy(), resolver ?? StubHostAddressResolver.Returning(PublicAddress));
|
|
|
|
|
|
2026-09-13 16:28:47 +00:00
|
|
|
public static NodeRequestBudget Quota(Action<NodeQuotaOptions>? configure = null)
|
2026-09-11 22:02:46 +00:00
|
|
|
{
|
|
|
|
|
var options = new NodeQuotaOptions();
|
|
|
|
|
configure?.Invoke(options);
|
2026-09-13 16:28:47 +00:00
|
|
|
return new NodeRequestBudget(options);
|
2026-09-11 22:02:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static NodePermissionPolicy Permissions(Action<NodePermissionOptions>? configure = null)
|
|
|
|
|
{
|
|
|
|
|
var options = new NodePermissionOptions();
|
|
|
|
|
configure?.Invoke(options);
|
|
|
|
|
return new NodePermissionPolicy(options);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static IReadOnlyList<IPAddress> Ips(params string[] addresses)
|
|
|
|
|
=> addresses.Select(IPAddress.Parse).ToArray();
|
|
|
|
|
}
|