mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
Merge pull request #306 from Noggog/pmap-test-graceful-timeout
Improved PMap tests to timeout gracefully if starved
This commit is contained in:
commit
05fd3225fa
@ -17,5 +17,33 @@ namespace Wabbajack
|
|||||||
onException(ex);
|
onException(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// returns a Task that will await the input task, but fire an action if it takes longer than a given time
|
||||||
|
/// </summary>
|
||||||
|
public static async Task TimeoutButContinue(this Task task, TimeSpan timeout, Action actionOnTimeout)
|
||||||
|
{
|
||||||
|
var timeoutTask = Task.Delay(timeout);
|
||||||
|
var completedTask = await Task.WhenAny(task, timeoutTask).ConfigureAwait(false);
|
||||||
|
if (completedTask == timeoutTask)
|
||||||
|
{
|
||||||
|
actionOnTimeout();
|
||||||
|
await task.ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// returns a Task that will await the input task, but fire an action if it takes longer than a given time
|
||||||
|
/// </summary>
|
||||||
|
public static async Task<TRet> TimeoutButContinue<TRet>(this Task<TRet> task, TimeSpan timeout, Action actionOnTimeout)
|
||||||
|
{
|
||||||
|
var timeoutTask = Task.Delay(timeout);
|
||||||
|
var completedTask = await Task.WhenAny(task, timeoutTask).ConfigureAwait(false);
|
||||||
|
if (completedTask == timeoutTask)
|
||||||
|
{
|
||||||
|
actionOnTimeout();
|
||||||
|
}
|
||||||
|
return await task.ConfigureAwait(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,8 +12,9 @@ namespace Wabbajack.Test
|
|||||||
[TestClass]
|
[TestClass]
|
||||||
public class PMapTests
|
public class PMapTests
|
||||||
{
|
{
|
||||||
const int TypicalThreadCount = 2;
|
const int TypicalThreadCount = 6;
|
||||||
const int TypicalDelayMS = 50;
|
const int TypicalDelayMS = 50;
|
||||||
|
const int TimeoutSeconds = 15;
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public async Task Typical_Action()
|
public async Task Typical_Action()
|
||||||
@ -22,7 +23,7 @@ namespace Wabbajack.Test
|
|||||||
{
|
{
|
||||||
var input = Enumerable.Range(0, TypicalThreadCount * 2).ToArray();
|
var input = Enumerable.Range(0, TypicalThreadCount * 2).ToArray();
|
||||||
var output = new List<int>();
|
var output = new List<int>();
|
||||||
await Enumerable.Range(0, TypicalThreadCount * 2)
|
var workTask = Enumerable.Range(0, TypicalThreadCount * 2)
|
||||||
.PMap(queue, (item) =>
|
.PMap(queue, (item) =>
|
||||||
{
|
{
|
||||||
Assert.IsTrue(WorkQueue.WorkerThread);
|
Assert.IsTrue(WorkQueue.WorkerThread);
|
||||||
@ -32,6 +33,7 @@ namespace Wabbajack.Test
|
|||||||
output.Add(item);
|
output.Add(item);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
await workTask.TimeoutButContinue(TimeSpan.FromSeconds(TimeoutSeconds), () => throw new TimeoutException());
|
||||||
Assert.IsTrue(input.SequenceEqual(output.OrderBy(i => i)));
|
Assert.IsTrue(input.SequenceEqual(output.OrderBy(i => i)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -42,13 +44,14 @@ namespace Wabbajack.Test
|
|||||||
using (var queue = new WorkQueue(TypicalThreadCount))
|
using (var queue = new WorkQueue(TypicalThreadCount))
|
||||||
{
|
{
|
||||||
var input = Enumerable.Range(0, TypicalThreadCount * 2).ToArray();
|
var input = Enumerable.Range(0, TypicalThreadCount * 2).ToArray();
|
||||||
var results = await Enumerable.Range(0, TypicalThreadCount * 2)
|
var workTask = Enumerable.Range(0, TypicalThreadCount * 2)
|
||||||
.PMap(queue, (item) =>
|
.PMap(queue, (item) =>
|
||||||
{
|
{
|
||||||
Assert.IsTrue(WorkQueue.WorkerThread);
|
Assert.IsTrue(WorkQueue.WorkerThread);
|
||||||
Thread.Sleep(TypicalDelayMS);
|
Thread.Sleep(TypicalDelayMS);
|
||||||
return item.ToString();
|
return item.ToString();
|
||||||
});
|
});
|
||||||
|
var results = await workTask.TimeoutButContinue(TimeSpan.FromSeconds(TimeoutSeconds), () => throw new TimeoutException());
|
||||||
Assert.IsTrue(input.Select(i => i.ToString()).SequenceEqual(results));
|
Assert.IsTrue(input.Select(i => i.ToString()).SequenceEqual(results));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -60,7 +63,7 @@ namespace Wabbajack.Test
|
|||||||
{
|
{
|
||||||
var input = Enumerable.Range(0, TypicalThreadCount * 2).ToArray();
|
var input = Enumerable.Range(0, TypicalThreadCount * 2).ToArray();
|
||||||
var output = new List<int>();
|
var output = new List<int>();
|
||||||
await Enumerable.Range(0, TypicalThreadCount * 2)
|
var workTask = Enumerable.Range(0, TypicalThreadCount * 2)
|
||||||
.PMap(queue, async (item) =>
|
.PMap(queue, async (item) =>
|
||||||
{
|
{
|
||||||
Assert.IsTrue(WorkQueue.WorkerThread);
|
Assert.IsTrue(WorkQueue.WorkerThread);
|
||||||
@ -70,6 +73,7 @@ namespace Wabbajack.Test
|
|||||||
output.Add(item);
|
output.Add(item);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
await workTask.TimeoutButContinue(TimeSpan.FromSeconds(TimeoutSeconds), () => throw new TimeoutException());
|
||||||
Assert.IsTrue(input.SequenceEqual(output.OrderBy(i => i)));
|
Assert.IsTrue(input.SequenceEqual(output.OrderBy(i => i)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -80,13 +84,14 @@ namespace Wabbajack.Test
|
|||||||
using (var queue = new WorkQueue(TypicalThreadCount))
|
using (var queue = new WorkQueue(TypicalThreadCount))
|
||||||
{
|
{
|
||||||
var input = Enumerable.Range(0, TypicalThreadCount * 2).ToArray();
|
var input = Enumerable.Range(0, TypicalThreadCount * 2).ToArray();
|
||||||
var results = await Enumerable.Range(0, TypicalThreadCount * 2)
|
var workTask = Enumerable.Range(0, TypicalThreadCount * 2)
|
||||||
.PMap(queue, async (item) =>
|
.PMap(queue, async (item) =>
|
||||||
{
|
{
|
||||||
Assert.IsTrue(WorkQueue.WorkerThread);
|
Assert.IsTrue(WorkQueue.WorkerThread);
|
||||||
await Task.Delay(TypicalDelayMS);
|
await Task.Delay(TypicalDelayMS);
|
||||||
return item.ToString();
|
return item.ToString();
|
||||||
});
|
});
|
||||||
|
var results = await workTask.TimeoutButContinue(TimeSpan.FromSeconds(TimeoutSeconds), () => throw new TimeoutException());
|
||||||
Assert.IsTrue(input.Select(i => i.ToString()).SequenceEqual(results));
|
Assert.IsTrue(input.Select(i => i.ToString()).SequenceEqual(results));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -99,7 +104,7 @@ namespace Wabbajack.Test
|
|||||||
var input = Enumerable.Range(0, TypicalThreadCount * 2).ToArray();
|
var input = Enumerable.Range(0, TypicalThreadCount * 2).ToArray();
|
||||||
var inputConstructedResults = input.SelectMany(i => Enumerable.Range(i * 100, TypicalThreadCount * 2));
|
var inputConstructedResults = input.SelectMany(i => Enumerable.Range(i * 100, TypicalThreadCount * 2));
|
||||||
var output = new List<int>();
|
var output = new List<int>();
|
||||||
await Enumerable.Range(0, TypicalThreadCount * 2)
|
var workTask = Enumerable.Range(0, TypicalThreadCount * 2)
|
||||||
.PMap(queue, async (item) =>
|
.PMap(queue, async (item) =>
|
||||||
{
|
{
|
||||||
Assert.IsTrue(WorkQueue.WorkerThread);
|
Assert.IsTrue(WorkQueue.WorkerThread);
|
||||||
@ -114,6 +119,7 @@ namespace Wabbajack.Test
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
await workTask.TimeoutButContinue(TimeSpan.FromSeconds(TimeoutSeconds), () => throw new TimeoutException());
|
||||||
Assert.IsTrue(inputConstructedResults.SequenceEqual(output.OrderBy(i => i)));
|
Assert.IsTrue(inputConstructedResults.SequenceEqual(output.OrderBy(i => i)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -125,7 +131,7 @@ namespace Wabbajack.Test
|
|||||||
{
|
{
|
||||||
var input = Enumerable.Range(0, TypicalThreadCount * 2).ToArray();
|
var input = Enumerable.Range(0, TypicalThreadCount * 2).ToArray();
|
||||||
var inputConstructedResults = input.SelectMany(i => Enumerable.Range(i * 100, TypicalThreadCount * 2));
|
var inputConstructedResults = input.SelectMany(i => Enumerable.Range(i * 100, TypicalThreadCount * 2));
|
||||||
var results = await Enumerable.Range(0, TypicalThreadCount * 2)
|
var workTask = Enumerable.Range(0, TypicalThreadCount * 2)
|
||||||
.PMap(queue, async (item) =>
|
.PMap(queue, async (item) =>
|
||||||
{
|
{
|
||||||
Assert.IsTrue(WorkQueue.WorkerThread);
|
Assert.IsTrue(WorkQueue.WorkerThread);
|
||||||
@ -137,6 +143,7 @@ namespace Wabbajack.Test
|
|||||||
return subItem;
|
return subItem;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
var results = await workTask.TimeoutButContinue(TimeSpan.FromSeconds(TimeoutSeconds), () => throw new TimeoutException());
|
||||||
Assert.IsTrue(inputConstructedResults.SequenceEqual(results.SelectMany(i => i)));
|
Assert.IsTrue(inputConstructedResults.SequenceEqual(results.SelectMany(i => i)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -149,7 +156,7 @@ namespace Wabbajack.Test
|
|||||||
var input = Enumerable.Range(0, TypicalThreadCount * 2).ToArray();
|
var input = Enumerable.Range(0, TypicalThreadCount * 2).ToArray();
|
||||||
var inputConstructedResults = input.SelectMany(i => Enumerable.Range(i * 100, TypicalThreadCount * 2));
|
var inputConstructedResults = input.SelectMany(i => Enumerable.Range(i * 100, TypicalThreadCount * 2));
|
||||||
var output = new List<int>();
|
var output = new List<int>();
|
||||||
await Enumerable.Range(0, TypicalThreadCount * 2)
|
var workTask = Enumerable.Range(0, TypicalThreadCount * 2)
|
||||||
.PMap(queue, async (item) =>
|
.PMap(queue, async (item) =>
|
||||||
{
|
{
|
||||||
Assert.IsTrue(WorkQueue.WorkerThread);
|
Assert.IsTrue(WorkQueue.WorkerThread);
|
||||||
@ -164,6 +171,7 @@ namespace Wabbajack.Test
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
await workTask.TimeoutButContinue(TimeSpan.FromSeconds(TimeoutSeconds), () => throw new TimeoutException());
|
||||||
Assert.IsTrue(inputConstructedResults.SequenceEqual(output.OrderBy(i => i)));
|
Assert.IsTrue(inputConstructedResults.SequenceEqual(output.OrderBy(i => i)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -175,7 +183,7 @@ namespace Wabbajack.Test
|
|||||||
{
|
{
|
||||||
var input = Enumerable.Range(0, TypicalThreadCount * 2).ToArray();
|
var input = Enumerable.Range(0, TypicalThreadCount * 2).ToArray();
|
||||||
var inputConstructedResults = input.SelectMany(i => Enumerable.Range(i * 100, TypicalThreadCount * 2));
|
var inputConstructedResults = input.SelectMany(i => Enumerable.Range(i * 100, TypicalThreadCount * 2));
|
||||||
var results = await Enumerable.Range(0, TypicalThreadCount * 2)
|
var workTask = Enumerable.Range(0, TypicalThreadCount * 2)
|
||||||
.PMap(queue, async (item) =>
|
.PMap(queue, async (item) =>
|
||||||
{
|
{
|
||||||
Assert.IsTrue(WorkQueue.WorkerThread);
|
Assert.IsTrue(WorkQueue.WorkerThread);
|
||||||
@ -187,6 +195,7 @@ namespace Wabbajack.Test
|
|||||||
return subItem;
|
return subItem;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
var results = await workTask.TimeoutButContinue(TimeSpan.FromSeconds(TimeoutSeconds), () => throw new TimeoutException());
|
||||||
Assert.IsTrue(inputConstructedResults.SequenceEqual(results.SelectMany(i => i)));
|
Assert.IsTrue(inputConstructedResults.SequenceEqual(results.SelectMany(i => i)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -198,7 +207,7 @@ namespace Wabbajack.Test
|
|||||||
{
|
{
|
||||||
var input = Enumerable.Range(0, TypicalThreadCount * 2).ToArray();
|
var input = Enumerable.Range(0, TypicalThreadCount * 2).ToArray();
|
||||||
var inputConstructedResults = input.SelectMany(i => Enumerable.Range(i * 100, TypicalThreadCount * 2));
|
var inputConstructedResults = input.SelectMany(i => Enumerable.Range(i * 100, TypicalThreadCount * 2));
|
||||||
var results = await Enumerable.Range(0, TypicalThreadCount * 2)
|
var workTask = Enumerable.Range(0, TypicalThreadCount * 2)
|
||||||
.PMap(queue, async (item) =>
|
.PMap(queue, async (item) =>
|
||||||
{
|
{
|
||||||
Assert.IsTrue(WorkQueue.WorkerThread);
|
Assert.IsTrue(WorkQueue.WorkerThread);
|
||||||
@ -213,6 +222,7 @@ namespace Wabbajack.Test
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
var results = await workTask.TimeoutButContinue(TimeSpan.FromSeconds(TimeoutSeconds), () => throw new TimeoutException());
|
||||||
Assert.IsTrue(inputConstructedResults.SequenceEqual(results.SelectMany(i => i)));
|
Assert.IsTrue(inputConstructedResults.SequenceEqual(results.SelectMany(i => i)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
29
Wabbajack.Test/TaskExtTests.cs
Normal file
29
Wabbajack.Test/TaskExtTests.cs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
|
||||||
|
namespace Wabbajack.Test
|
||||||
|
{
|
||||||
|
[TestClass]
|
||||||
|
public class TaskExtTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public async Task TimeoutButContinue_Typical()
|
||||||
|
{
|
||||||
|
bool timedOut = false;
|
||||||
|
await Task.Delay(100).TimeoutButContinue(TimeSpan.FromSeconds(1), () => timedOut = true);
|
||||||
|
Assert.IsFalse(timedOut);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public async Task TimeoutButContinue_TimedOut()
|
||||||
|
{
|
||||||
|
bool timedOut = false;
|
||||||
|
await Task.Delay(300).TimeoutButContinue(TimeSpan.FromMilliseconds(100), () => timedOut = true);
|
||||||
|
Assert.IsTrue(timedOut);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -113,6 +113,7 @@
|
|||||||
<Compile Include="PMapTests.cs" />
|
<Compile Include="PMapTests.cs" />
|
||||||
<Compile Include="RestartingDownloadsTests.cs" />
|
<Compile Include="RestartingDownloadsTests.cs" />
|
||||||
<Compile Include="SimpleHTTPServer.cs" />
|
<Compile Include="SimpleHTTPServer.cs" />
|
||||||
|
<Compile Include="TaskExtTests.cs" />
|
||||||
<Compile Include="TestUtils.cs" />
|
<Compile Include="TestUtils.cs" />
|
||||||
<Compile Include="SanityTests.cs" />
|
<Compile Include="SanityTests.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
Loading…
x
Reference in New Issue
Block a user