// case 5 or 6. public async Task FailedTransactionWillBeRetriedOnNewEvent() { var persistentCollector = new TestPersistentCollectorFailure(); var persistentCollectors = new List <IPersistentCollector>() { persistentCollector }; var eventCollector = new EventCollector(persistentCollectors); var partitionId = new Guid(); persistentCollector.DontAcceptChangesNow(); await Assert.ThrowsAnyAsync <Exception>(async() => await eventCollector.TransactionApplied(partitionId, 0, 1, this.Data)); persistentCollector.AcceptChangesNow(); await eventCollector.TransactionApplied(partitionId, 1, 2, this.Data); var changes = persistentCollector.Changes; Assert.True(1 == changes.Count); Assert.Equal(2, changes[0].Transactions.Count); Assert.Equal(1, changes[0].Transactions[0].Lsn); Assert.Equal(2, changes[0].Transactions[1].Lsn); }
// case 7 and more :) public async Task RandomizedRealWorldTest() { var persistentCollector = new TestPersistentCollectorFailure(); var persistentCollectors = new List <IPersistentCollector>() { persistentCollector }; var eventCollector = new EventCollector(persistentCollectors); var partitionId = new Guid(); var rand = new Random(); const int MaxTimeToWaitInMs = 1000 * 20; // 20 seconds of test Func <Task> randomPCFailureFunc = async() => { var watch = Stopwatch.StartNew(); while (watch.ElapsedMilliseconds < MaxTimeToWaitInMs) { if (rand.Next(0, 10) < 3) // fail upload 30% time. { persistentCollector.DontAcceptChangesNow(); } else { persistentCollector.AcceptChangesNow(); } await Task.Delay(rand.Next(3, 20)); } }; var lsnTaskDict = new Dictionary <long, Task>(); var lsn = 0; Func <Task> addEvents = async() => { var watch = Stopwatch.StartNew(); while (watch.ElapsedMilliseconds < MaxTimeToWaitInMs) { var t = eventCollector.TransactionApplied(partitionId, lsn - 1, lsn, this.Data); lsnTaskDict.Add(lsn, t); lsn += 1; if (rand.Next(0, 10) < 4) // sleep 40% time. { await Task.Delay(rand.Next(0, 10)); } } }; Task.WaitAll(new Task[] { randomPCFailureFunc(), addEvents() }); persistentCollector.AcceptChangesNow(); await eventCollector.TransactionApplied(partitionId, lsn - 1, lsn, this.Data); var changes = persistentCollector.Changes; var allTransactions = changes.SelectMany((pc) => pc.Transactions).ToList(); var monotinicallyIncreasingLsns = allTransactions.Zip(allTransactions.Skip(1), (t1, t2) => t1.Lsn + 1 == t2.Lsn) .All(b => b == true); Assert.True(monotinicallyIncreasingLsns, "Some transaction is lost."); Assert.True(allTransactions[0].Lsn == 0, "First lsn is not right"); Assert.True(allTransactions.Last().Lsn == lsn, "Last lsn is not right"); }