using System.Net; using System.Net.Sockets; using w4c_workflows.Services.Security; using w4c_workflows.Services.Nodes; namespace w4c_workflows.Tests; /// /// Deterministic for egress tests: returns a /// fixed address set per host and records every query, so tests never touch DNS. /// internal sealed class StubHostAddressResolver : IHostAddressResolver { private readonly Func> _resolve; public StubHostAddressResolver(Func> resolve) => _resolve = resolve; public List Queries { get; } = new(); public Task> 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 { /// A routable public address used as the default stub answer. public const string PublicAddress = "93.184.216.34"; public static EgressPolicy Policy(Action? 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)); public static NodeRequestBudget Quota(Action? configure = null) { var options = new NodeQuotaOptions(); configure?.Invoke(options); return new NodeRequestBudget(options); } public static NodePermissionPolicy Permissions(Action? configure = null) { var options = new NodePermissionOptions(); configure?.Invoke(options); return new NodePermissionPolicy(options); } public static IReadOnlyList Ips(params string[] addresses) => addresses.Select(IPAddress.Parse).ToArray(); }