2019-12-17 23:17:44 +00:00
|
|
|
|
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;
|
2020-08-11 15:37:17 +00:00
|
|
|
|
using Wabbajack.Lib;
|
2019-12-17 23:17:44 +00:00
|
|
|
|
using Wabbajack.Lib.Downloaders;
|
2020-03-28 18:22:53 +00:00
|
|
|
|
using Xunit;
|
|
|
|
|
using Xunit.Abstractions;
|
|
|
|
|
using Xunit.Sdk;
|
2019-12-17 23:17:44 +00:00
|
|
|
|
|
|
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-01 11:47:47 +00:00
|
|
|
|
public class RestartingDownloadsTests : IDisposable
|
2019-12-17 23:17:44 +00:00
|
|
|
|
{
|
2020-04-01 11:47:47 +00:00
|
|
|
|
private IDisposable _unsubInfo;
|
|
|
|
|
private IDisposable _unsubIntevention;
|
2020-03-28 18:22:53 +00:00
|
|
|
|
private ITestOutputHelper TestContext { get; set; }
|
2019-12-17 23:17:44 +00:00
|
|
|
|
|
2020-03-28 18:22:53 +00:00
|
|
|
|
public RestartingDownloadsTests(ITestOutputHelper helper)
|
2019-12-17 23:17:44 +00:00
|
|
|
|
{
|
2020-03-28 18:22:53 +00:00
|
|
|
|
TestContext = helper;
|
2020-04-01 11:47:47 +00:00
|
|
|
|
_unsubInfo = Utils.LogMessages.OfType<IInfo>().Subscribe(onNext: msg => TestContext.WriteLine(msg.ShortDescription));
|
|
|
|
|
_unsubIntevention = Utils.LogMessages.OfType<IUserIntervention>().Subscribe(msg =>
|
2020-01-13 21:11:07 +00:00
|
|
|
|
TestContext.WriteLine("ERROR: User intervention required: " + msg.ShortDescription));
|
2019-12-17 23:17:44 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-03-28 18:22:53 +00:00
|
|
|
|
[Fact]
|
2019-12-17 23:17:44 +00:00
|
|
|
|
public async Task DownloadResume()
|
|
|
|
|
{
|
2020-05-28 02:43:57 +00:00
|
|
|
|
await using var testFile = new TempFile();
|
2020-03-28 18:22:53 +00:00
|
|
|
|
using var server = new CrappyRandomServer();
|
2020-04-09 20:20:34 +00:00
|
|
|
|
var state = new HTTPDownloader.State($"http://localhost:{server.Port}/foo");
|
|
|
|
|
|
2020-03-28 18:22:53 +00:00
|
|
|
|
await state.Download(testFile.Path);
|
2019-12-17 23:17:44 +00:00
|
|
|
|
|
2020-03-28 18:22:53 +00:00
|
|
|
|
Assert.Equal(server.Data, await testFile.Path.ReadAllBytesAsync());
|
2019-12-17 23:17:44 +00:00
|
|
|
|
|
2020-05-26 11:31:11 +00:00
|
|
|
|
await testFile.Path.DeleteAsync();
|
2019-12-17 23:17:44 +00:00
|
|
|
|
}
|
2020-04-01 11:47:47 +00:00
|
|
|
|
|
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
|
|
|
|
_unsubInfo?.Dispose();
|
|
|
|
|
_unsubIntevention?.Dispose();
|
|
|
|
|
}
|
2019-12-17 23:17:44 +00:00
|
|
|
|
}
|
|
|
|
|
}
|