private async Task RestartServiceConnectionCoreAsync(int index) { Func <Task <bool> > tryNewConnection = async() => { var connection = CreateServiceConnectionCore(); ReplaceFixedConnections(index, connection); _ = StartCoreAsync(connection); await connection.ConnectionInitializedTask; return(connection.Status == ServiceConnectionStatus.Connected); }; await backOffPolicy.CallProbeWithBackOffAsync(tryNewConnection, GetRetryDelay); }
static async Task RunProbeTests(TestData testData) { // initialize a few things int _funcCallNumber = 0; var policy = new BackOffPolicy(); testData.Results = new ProbeResult[testData.Params.Length]; DateTime startTime = DateTime.UtcNow; Task[] probeTestTasks = new Task[testData.Params.Length]; for (int i = 0; i < testData.Params.Length; i++) { int index = i; var currentProbe = testData.Params[index]; testData.Results[index] = new ProbeResult(); Func <Task <bool> > probeFunc = async() => { var result = testData.Results[index]; result.ActualCallTime = DateTime.UtcNow - startTime; result.ActualCallOrder = Interlocked.Increment(ref _funcCallNumber); Interlocked.Increment(ref result.ActualNumberOfCalls); await Task.Delay(currentProbe.Duration); if (currentProbe.Throws) { throw new Exception("exception from probe func"); } return(currentProbe.Result); }; Func <Task> testFunc = async() => { try { // This delay effectively defines the order of the calls await Task.Delay(currentProbe.InitialDelay); testData.Results[index].ActualResult = await policy.CallProbeWithBackOffAsync(probeFunc, testData.BkOffFunc); } catch (Exception ex) { testData.Results[index].ActualException = ex; } }; probeTestTasks[index] = testFunc(); } await Task.WhenAll(probeTestTasks); // verify for (int i = 0; i < testData.Params.Length; i++) { var param = testData.Params[i]; var result = testData.Results[i]; Assert.Equal(1, result.ActualNumberOfCalls); Assert.Equal(param.Result, result.ActualResult); Assert.NotEqual((result.ActualException == null), param.Throws); // knowing the actual order of the func call we can compare it with the expected time // ActualCallOrder starts with 1 var expectedTime = testData.ExpectedCallTimes[result.ActualCallOrder - 1]; Assert.False( result.ActualCallTime <expectedTime - _underrunLeeway || // too early result.ActualCallTime> expectedTime + _overrunLeeway); // too late } }