public void GetDatabaseTimeCached_BestLatency() { var tests = new ListOfTuples <ListOfTuples <int, double>, int> { // Format: 3 x (db latency ms, db clock offset seconds) => expected clock offset { new ListOfTuples <int, double> { { 20, 11 }, { 30, 22 }, { 40, 33 } }, 11 }, { new ListOfTuples <int, double> { { 40, 11 }, { 20, 22 }, { 30, 33 } }, 22 }, { new ListOfTuples <int, double> { { 40, 11 }, { 30, 22 }, { 20, 33 } }, 33 }, }; for (int t = 0; t < tests.Count(); t++) { var test = tests[t]; var dbUsage = new List <bool>(); TimeSpan lastDbOffset = TimeSpan.MaxValue; DatabaseTimeCache.Reset(); DateTime systemTime = new DateTime(2001, 2, 3, 4, 5, 6); foreach (var sqlClock in test.Item1.Concat(new[] { Tuple.Create <int, double>(70, 70) })) { DateTime dbTime = DateTime.MinValue; bool dbRead = false; DateTime computed = DatabaseTimeCache.GetDatabaseTimeCached( () => { dbRead = true; // There is no need to use Thred.Sleep(sqlClock.Item1) here, because db latency is simulated by increasing the systemTime value. return(dbTime = systemTime.AddSeconds(sqlClock.Item2)); }, () => { return(systemTime = systemTime.AddMilliseconds(sqlClock.Item1)); }); dbUsage.Add(dbRead); lastDbOffset = computed.Subtract(systemTime); Console.WriteLine($"Test {t} {sqlClock.Item1} {sqlClock.Item2}: sys {systemTime.ToString("o")}, db {dbTime.ToString("o")} " + $"=> {ReportDbOrCache(dbRead)} {computed.ToString("o")}"); } Assert.AreEqual("read db, read db, read db, read cache", TestUtility.Dump(dbUsage, ReportDbOrCache), $"Test {t}: Should use cache after 3rd query from database."); Assert.AreEqual(test.Item2, Convert.ToInt32(lastDbOffset.TotalSeconds), $"Test {t}: When using datetime cache, the database offset should be the one taken with the smallest latency."); } }
private void RunTests(DateTime baseSysTime, TimeSpan dbOffset, ListOfTuples <int, double, bool> tests) { DatabaseTimeCache.Reset(); foreach (var test in tests) { DateTime systemTime = baseSysTime.AddMinutes(test.Item1).AddSeconds(test.Item2); DateTime dbTime = systemTime.Add(dbOffset); bool dbRead = false; DateTime computed = DatabaseTimeCache.GetDatabaseTimeCached(() => { dbRead = true; return(dbTime); }, () => systemTime); string report = $"Test {test.Item1} {test.Item2}: sys {systemTime.ToString("o")}, db {dbTime.ToString("o")} " + $"=> {ReportDbOrCache(dbRead)} {computed.ToString("o")}"; Console.WriteLine(report); Assert.AreEqual(ReportDbOrCache(test.Item3), ReportDbOrCache(dbRead), report); Assert.AreEqual(dbTime, computed, report); } }