Skip to content

Commit 6b5a433

Browse files
author
Martijn Hoekstra
committed
uploads end in-order
1 parent b64913c commit 6b5a433

File tree

6 files changed

+444
-399
lines changed

6 files changed

+444
-399
lines changed
Lines changed: 23 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using Microsoft.VisualStudio.TestTools.UnitTesting;
22
using System;
33
using System.Collections.Generic;
4+
using System.Linq;
45
using System.Threading.Tasks;
56

67
namespace Hotsapi.Uploader.Common.Test
@@ -14,68 +15,27 @@ public static Task ShortRandomDelay()
1415
var delay = r.Next(100, 200);
1516
return Task.Delay(delay);
1617
}
17-
private static IEnumerable<ReplayFile> ThreeInOrder
18+
private static IEnumerable<ReplayFile> FilesInOrder
1819
{
1920
get {
20-
var one = new ReplayFile("one") {
21-
Created = new DateTime(2020, 1, 1, 0, 0, 1)
22-
};
23-
var two = new ReplayFile("two") {
24-
Created = new DateTime(2020, 1, 1, 0, 0, 10)
25-
};
26-
var three = new ReplayFile("three") {
27-
Created = new DateTime(2020, 1, 1, 0, 0, 20)
28-
};
29-
var initialFiles = new List<ReplayFile>() { one, two, three };
30-
return initialFiles;
21+
var next = new DateTime(2020, 1, 1, 0, 0, 0);
22+
var increment = new TimeSpan(0, 0, 1);
23+
var rand = new Random();
24+
var nums = Enumerable.Range(1, 24).OrderBy(rf => rand.NextDouble());
25+
26+
return nums.Select(i => {
27+
next += increment;
28+
return new ReplayFile($"upload_{i}") {
29+
Created = next
30+
};
31+
});
32+
3133
}
3234
}
33-
34-
[TestMethod]
35-
[Ignore("Known intermittant failure: multiple uploads are started in parallel and don't always start in order")]
36-
public async Task InitialFilesStartInOrder()
37-
{
38-
var initialFiles = ThreeInOrder;
39-
40-
var manager = new Manager(new MockStorage(initialFiles));
41-
var uploadTester = new MockUploader();
42-
43-
var promise = new TaskCompletionSource<int>();
44-
Task done = promise.Task;
45-
46-
var uploadsSeen = 0;
47-
var l = new object();
48-
ReplayFile lastUploadStarted = null;
49-
uploadTester.SetUploadCallback(async rf => {
50-
if (lastUploadStarted != null) {
51-
try {
52-
Assert.IsTrue(rf.Created >= lastUploadStarted.Created, $"upload started out of order, {lastUploadStarted} started after {rf}");
53-
} catch (Exception e) {
54-
promise.TrySetException(e);
55-
}
56-
}
57-
lastUploadStarted = rf;
58-
await ShortRandomDelay();
59-
var isDone = false;
60-
lock (l) {
61-
uploadsSeen++;
62-
isDone = uploadsSeen >= 3;
63-
}
64-
if (isDone) {
65-
promise.TrySetResult(uploadsSeen);
66-
}
67-
});
68-
69-
manager.Start(new NoNewFilesMonitor(), new MockAnalizer(), uploadTester);
70-
await done;
71-
}
72-
73-
7435

7536
[TestMethod]
76-
[Ignore("Known intermittant failure: multiple uploads are started in parallel and don't always end in order")]
7737
public async Task InitialFilesEndInorder() {
78-
var initialFiles = ThreeInOrder;
38+
var initialFiles = FilesInOrder;
7939

8040
var manager = new Manager(new MockStorage(initialFiles));
8141
var uploadTester = new MockUploader();
@@ -85,11 +45,11 @@ public async Task InitialFilesEndInorder() {
8545
var uploadsSeen = 0;
8646
var l = new object();
8747
ReplayFile lastUploadFinished = null;
88-
uploadTester.SetUploadCallback(async rf => {
89-
await ShortRandomDelay();
48+
uploadTester.UploadFinished = async rf => {
9049
if (lastUploadFinished != null) {
9150
try {
92-
Assert.IsTrue(rf.Created >= lastUploadFinished.Created, $"upload completed out of order, {lastUploadFinished} completed after {rf}");
51+
var isInOrder = rf.Created >= lastUploadFinished.Created;
52+
Assert.IsTrue(isInOrder, $"upload completed out of order, {rf} completed after {lastUploadFinished}");
9353
}
9454
catch (Exception e) {
9555
promise.TrySetException(e);
@@ -104,7 +64,7 @@ public async Task InitialFilesEndInorder() {
10464
if (isDone) {
10565
promise.TrySetResult(uploadsSeen);
10666
}
107-
});
67+
};
10868

10969
manager.Start(new NoNewFilesMonitor(), new MockAnalizer(), uploadTester);
11070
await done;
@@ -113,29 +73,27 @@ public async Task InitialFilesEndInorder() {
11373
[TestMethod]
11474
public async Task AllInitialFilesProcessed()
11575
{
116-
var initialFiles = ThreeInOrder;
76+
var initialFiles = FilesInOrder;
11777

11878
var manager = new Manager(new MockStorage(initialFiles));
11979
var uploadTester = new MockUploader();
12080
var done = new TaskCompletionSource<int>();
12181

12282
var uploadsSeen = 0;
12383
object l = new object();
124-
uploadTester.SetUploadCallback(async rf => {
84+
uploadTester.UploadFinished = async rf => {
12585
await ShortRandomDelay();
12686
lock (l) {
12787
uploadsSeen++;
12888
if (uploadsSeen >= 3) {
12989
done.SetResult(uploadsSeen);
13090
}
13191
}
132-
});
92+
};
13393

13494
manager.Start(new NoNewFilesMonitor(), new MockAnalizer(), uploadTester);
13595
var num = await done.Task;
136-
//var finished = await Task.WhenAny(Task.Delay(4000), done.Task);
137-
//await finished;
138-
Assert.AreEqual(3, uploadsSeen);
96+
Assert.AreEqual(3, num);
13997
}
14098
}
14199
}

Hotsapi.Uploader.Common.Test/MockAnalizer.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ private class MockAnalizer : IAnalyzer
99
public int MinimumBuild { get; set; }
1010
public Replay Analyze(ReplayFile file) {
1111
file.UploadStatus = UploadStatus.Preprocessed;
12-
return new Replay();
12+
return new Replay() {
13+
Timestamp = file.Created
14+
};
1315
}
1416
public string GetFingerprint(Replay replay) => "dummy fingerprint";
1517
}

Hotsapi.Uploader.Common.Test/MockUploader.cs

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,33 +10,27 @@ private class MockUploader : IUploader
1010
{
1111
public bool UploadToHotslogs { get; set; }
1212

13-
private Func<ReplayFile, Task> UploadCallback = _ => Task.CompletedTask;
14-
public void SetUploadCallback(Func<ReplayFile, Task> onUpload)
15-
{
16-
var old = UploadCallback;
17-
18-
UploadCallback = async (ReplayFile file) => {
19-
await old(file);
20-
await onUpload(file);
21-
};
22-
}
13+
public Func<ReplayFile, Task> UploadStarted { get; set; } = _ => Task.CompletedTask;
14+
public Func<ReplayFile, Task> UploadFinished { get; set; } = _ => Task.CompletedTask;
2315

2416
public async Task CheckDuplicate(IEnumerable<ReplayFile> replays)
2517
{
2618
foreach (var replay in replays) {
2719
replay.UploadStatus = UploadStatus.ReadyForUpload;
2820
}
29-
await ShortRandomDelay(); //todo: put this elsewhere
21+
await ShortRandomDelay();
3022
}
3123
public Task<int> GetMinimumBuild() => Task.FromResult(1);
32-
public Task Upload(ReplayFile file)
24+
public async Task Upload(ReplayFile file, Task mayComplete)
3325
{
34-
UploadCallback(file);
35-
return Task.CompletedTask;
26+
await UploadStarted(file);
27+
await Upload(file.Filename, mayComplete);
28+
await UploadFinished(file);
3629
}
37-
public async Task<UploadStatus> Upload(string file)
30+
public async Task<UploadStatus> Upload(string file, Task mayComplete)
3831
{
39-
await Task.Delay(100);
32+
await ShortRandomDelay();
33+
await mayComplete;
4034
return UploadStatus.Success;
4135
}
4236
}

Hotsapi.Uploader.Common/IUploader.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ public interface IUploader
88
bool UploadToHotslogs { get; set; }
99
Task CheckDuplicate(IEnumerable<ReplayFile> replays);
1010
Task<int> GetMinimumBuild();
11-
Task Upload(ReplayFile file);
12-
Task<UploadStatus> Upload(string file);
11+
Task Upload(ReplayFile file, Task mayComplete);
12+
Task<UploadStatus> Upload(string file, Task mayComplete);
1313
}
1414
}

0 commit comments

Comments
 (0)