105 lines
3.7 KiB
C#
105 lines
3.7 KiB
C#
using Microsoft.Extensions.Logging.Abstractions;
|
|||
|
|
|
||
|
|
using MongoDB.Entities;
|
||
|
|
|
||
|
|
using PrivaPub.Infrastructure.Geo;
|
||
|
|
using PrivaPub.Infrastructure.Statistics;
|
||
|
|
using PrivaPub.Models.Jobs;
|
||
|
|
using PrivaPub.Tests.Support;
|
||
|
|
|
||
|
|
using System.Net;
|
||
|
|
|
||
|
|
namespace PrivaPub.Tests.Infrastructure
|
||
|
|
{
|
||
|
|
[Trait("Category", "Integration")]
|
||
|
|
public sealed class CdnUpdaterTests : IAsyncLifetime
|
||
|
|
{
|
||
|
|
Peer _peer;
|
||
|
|
CdnRanges _ranges;
|
||
|
|
CdnUpdater _updater;
|
||
|
|
string _key;
|
||
|
|
|
||
|
|
public async ValueTask InitializeAsync()
|
||
|
|
{
|
||
|
|
Assert.SkipUnless(MongoFixture.Enabled, MongoFixture.Skip);
|
||
|
|
_peer = await Peer.Start();
|
||
|
|
_ranges = new CdnRanges();
|
||
|
|
_updater = new CdnUpdater(new Clients(), new StaticOptions<StatisticsOptions>(new StatisticsOptions()), _ranges, NullLogger<CdnUpdater>.Instance);
|
||
|
|
_key = $"edge{Guid.NewGuid():N}.example";
|
||
|
|
}
|
||
|
|
|
||
|
|
public async ValueTask DisposeAsync()
|
||
|
|
{
|
||
|
|
if (_peer != default)
|
||
|
|
await _peer.DisposeAsync();
|
||
|
|
}
|
||
|
|
|
||
|
|
sealed class Clients : IHttpClientFactory
|
||
|
|
{
|
||
|
|
public HttpClient CreateClient(string name) => new();
|
||
|
|
}
|
||
|
|
|
||
|
|
CdnProvider Provider() => new("Test Edge", _key, Array.Empty<int>(), new[]
|
||
|
|
{
|
||
|
|
new CdnList($"{_peer.A}/edge/v4", CdnListFormat.Lines),
|
||
|
|
new CdnList($"{_peer.A}/edge/v6", CdnListFormat.StringArray)
|
||
|
|
}, _ => false);
|
||
|
|
|
||
|
|
static CancellationToken Token => TestContext.Current.CancellationToken;
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public async Task The_published_ranges_are_downloaded_stored_and_used()
|
||
|
|
{
|
||
|
|
_peer.ServeText("/edge/v4", "198.51.100.0/24\n", "text/plain");
|
||
|
|
_peer.ServeText("/edge/v6", """["2001:db8::/32","192.0.2.9"]""", "application/json");
|
||
|
|
|
||
|
|
Assert.Equal(1, await _updater.Update(new[] { Provider() }, Token));
|
||
|
|
|
||
|
|
var stored = await DB.Default.Find<CdnRangeSet>().Match(s => s.Key == _key).ExecuteSingleAsync(Token);
|
||
|
|
Assert.Equal(new[] { "198.51.100.0/24", "2001:db8::/32", "192.0.2.9/32" }, stored.Ranges);
|
||
|
|
Assert.Equal("Test Edge", _ranges.Of(IPAddress.Parse("198.51.100.20"))?.Name);
|
||
|
|
Assert.Equal("Test Edge", _ranges.Of(IPAddress.Parse("192.0.2.9"))?.Name);
|
||
|
|
|
||
|
|
var restarted = new CdnRanges();
|
||
|
|
await restarted.Load(Token);
|
||
|
|
Assert.Equal("Test Edge", restarted.Of(IPAddress.Parse("2001:db8::7"))?.Name);
|
||
|
|
}
|
||
|
|
|
||
|
|
[Theory]
|
||
|
|
[InlineData("not a network")]
|
||
|
|
[InlineData("")]
|
||
|
|
public async Task A_broken_or_empty_list_keeps_the_stored_ranges(string broken)
|
||
|
|
{
|
||
|
|
_peer.ServeText("/edge/v4", "198.51.100.0/24", "text/plain");
|
||
|
|
_peer.ServeText("/edge/v6", "[]", "application/json");
|
||
|
|
Assert.Equal(1, await _updater.Update(new[] { Provider() }, Token));
|
||
|
|
|
||
|
|
_peer.ServeText("/edge/v4", broken, "text/plain");
|
||
|
|
Assert.Equal(0, await _updater.Update(new[] { Provider() }, Token));
|
||
|
|
|
||
|
|
Assert.Equal(new[] { "198.51.100.0/24" }, (await DB.Default.Find<CdnRangeSet>().Match(s => s.Key == _key).ExecuteSingleAsync(Token)).Ranges);
|
||
|
|
Assert.Equal("Test Edge", _ranges.Of(IPAddress.Parse("198.51.100.1"))?.Name);
|
||
|
|
}
|
||
|
|
|
||
|
|
// The real lists, from the CDNs themselves: set PRIVAPUB_TEST_CDN_LIVE=1 to check that every format still parses.
|
||
|
|
[Fact]
|
||
|
|
public async Task Every_cdns_real_list_still_parses()
|
||
|
|
{
|
||
|
|
Assert.SkipUnless(Environment.GetEnvironmentVariable("PRIVAPUB_TEST_CDN_LIVE") == "1", "set PRIVAPUB_TEST_CDN_LIVE=1 to download the real lists");
|
||
|
|
var listed = CdnCatalog.All.Where(p => p.Lists.Length > 0).ToList();
|
||
|
|
|
||
|
|
Assert.Equal(listed.Count, await _updater.Update(listed, Token));
|
||
|
|
|
||
|
|
Assert.Equal("Cloudflare", _ranges.Of(IPAddress.Parse("104.16.0.1"))?.Name);
|
||
|
|
foreach (var provider in listed)
|
||
|
|
Assert.True(_ranges.Status[provider.Key].Ranges > 0, provider.Name);
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public async Task An_unreachable_list_changes_nothing()
|
||
|
|
{
|
||
|
|
Assert.Equal(0, await _updater.Update(new[] { Provider() }, Token));
|
||
|
|
Assert.False(await DB.Default.Find<CdnRangeSet>().Match(s => s.Key == _key).ExecuteAnyAsync(Token));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|