wabbajack/Wabbajack.Test/RestartingDownloadsTests.cs

91 lines
2.9 KiB
C#

using System;
using System.Net;
using System.Reactive.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Alphaleonis.Win32.Filesystem;
using Wabbajack.Common;
using Wabbajack.Common.StatusFeed;
using Wabbajack.Lib.Downloaders;
using Xunit;
using Xunit.Abstractions;
using Xunit.Sdk;
namespace Wabbajack.Test
{
public class CrappyRandomServer : SimpleHTTPServer
{
private Random _random;
private readonly byte[] _data;
public byte[] Data => _data;
public CrappyRandomServer() : base("")
{
_random = new Random();
_data = new byte[_random.Next(1024 * 1024, 1024 * 2048)];
_random.NextBytes(_data);
}
protected override void Process(HttpListenerContext context)
{
context.Response.ContentType = "application/octet-stream";
context.Response.ContentLength64 = _data.Length;
context.Response.AddHeader("Accept-Ranges", "bytes");
context.Response.StatusCode = (int)HttpStatusCode.OK;
var range = context.Request.Headers.Get("Range");
int start = 0;
if (range != null)
{
var match = new Regex("(?<=bytes=)[0-9]+(?=\\-)").Match(range);
if (match != null)
{
start = int.Parse(match.ToString());
}
}
var end = Math.Min(start + _random.Next(1024 * 32, 1024 * 64), _data.Length);
context.Response.OutputStream.Write(_data, start, end - start);
context.Response.OutputStream.Flush();
Thread.Sleep(500);
context.Response.Abort();
}
}
public class RestartingDownloadsTests : IDisposable
{
private IDisposable _unsubInfo;
private IDisposable _unsubIntevention;
private ITestOutputHelper TestContext { get; set; }
public RestartingDownloadsTests(ITestOutputHelper helper)
{
TestContext = helper;
_unsubInfo = Utils.LogMessages.OfType<IInfo>().Subscribe(onNext: msg => TestContext.WriteLine(msg.ShortDescription));
_unsubIntevention = Utils.LogMessages.OfType<IUserIntervention>().Subscribe(msg =>
TestContext.WriteLine("ERROR: User intervention required: " + msg.ShortDescription));
}
[Fact]
public async Task DownloadResume()
{
await using var testFile = new TempFile();
using var server = new CrappyRandomServer();
var state = new HTTPDownloader.State($"http://localhost:{server.Port}/foo");
await state.Download(testFile.Path);
Assert.Equal(server.Data, await testFile.Path.ReadAllBytesAsync());
await testFile.Path.DeleteAsync();
}
public void Dispose()
{
_unsubInfo?.Dispose();
_unsubIntevention?.Dispose();
}
}
}