public async Task CreateQueueDbIfNeeded() { var connectionStringBuilder = new SqlConnectionStringBuilder(_connectionString); var dbName = connectionStringBuilder.InitialCatalog; connectionStringBuilder.InitialCatalog = "master"; var createDbQuery = string.Format(CreateDbQuery, dbName); await RetryHelper.Execute(async() => { using (var connection = new SqlConnection(connectionStringBuilder.ConnectionString)) using (var createDbCommand = new SqlCommand(createDbQuery, connection)) { await connection.OpenAsync(); await createDbCommand.ExecuteNonQueryAsync(); } }, IsConnectionResiliencyException); await RetryHelper.Execute(async() => { using (var connection = new SqlConnection(_connectionString)) using (var command = new SqlCommand(InitializeDbQuery, connection)) { await connection.OpenAsync(); await command.ExecuteNonQueryAsync(); } }, IsConnectionResiliencyException); }
public async Task AddEvent(string type, string body, string consistentHashKey) { if (type == null) { throw new ArgumentNullException(nameof(type)); } if (body == null) { throw new ArgumentNullException(nameof(body)); } await RetryHelper.Execute(async() => { using (var connection = new SqlConnection(_connectionString)) using (var command = new SqlCommand(InsertEventQuery, connection)) { command.Parameters.AddWithValue("@Type", type); command.Parameters.AddWithValue("@Body", body); command.Parameters.AddWithValue("@Source", _applicationName); command.Parameters.AddWithValue("@ConsistentHashKey", (object)consistentHashKey ?? DBNull.Value); await connection.OpenAsync(); await command.ExecuteNonQueryAsync(); } }, IsConnectionResiliencyException); }
public void Invoke_Instance_And_Static_Method_Win32_Process() { // Retries are sometimes necessary as underlying API call can return // ERROR_NOT_READY or occasionally ERROR_INVALID_BLOCK or ERROR_NOT_ENOUGH_MEMORY RetryHelper.Execute(() => { var processClass = new ManagementClass("Win32_Process"); object[] methodArgs = { "notepad.exe", null, null, 0 }; object resultObj = processClass.InvokeMethod("Create", methodArgs); var resultCode = (uint)resultObj; Assert.Equal(0u, resultCode); var processId = (uint)methodArgs[3]; Assert.True(0u != processId, $"Unexpected process ID: {processId}"); using (Process targetProcess = Process.GetProcessById((int)processId)) using (var process = new ManagementObject($"Win32_Process.Handle=\"{processId}\"")) { Assert.False(targetProcess.HasExited); resultObj = process.InvokeMethod("Terminate", new object[] { 0 }); resultCode = (uint)resultObj; Assert.Equal(0u, resultCode); Assert.True(targetProcess.HasExited); } }, maxAttempts: 10, retryWhen: e => e is XunitException); }
public void UserPreferenceChangingEventTest() { int element = 12; // Win32SystemColors.AppWorkSpace. Color oldColor = System.Drawing.SystemColors.AppWorkspace; // A call to ToArgb is necessary before changing the system colors because it initializes the knownColorTable. int oldColorArgb = oldColor.ToArgb(); int oldColorAbgr = GetColorRefValue(oldColor); Color newColor = oldColor != Color.Gold ? Color.Gold : Color.Silver; int newColorArgb = newColor.ToArgb(); int newColorAbgr = GetColorRefValue(newColor); Assert.NotEqual(newColorArgb, oldColorArgb); try { Assert.Equal(1, SetSysColors(1, new int[] { element }, new int[] { newColorAbgr })); RetryHelper.Execute(() => { Assert.Equal(newColorArgb, oldColor.ToArgb()); }); } finally { Assert.Equal(1, SetSysColors(1, new int[] { element }, new int[] { oldColorAbgr })); } }
public void ModulesAreDisposedWhenProcessIsDisposed() { Process process = CreateDefaultProcess(); // Very rarely, this call will fail with ERROR_PARTIAL_COPY; it only happened // so far on this particular test, the only one that creates a new process. // Assumption is that we need to give a little extra time. ProcessModuleCollection modulesCollection = null; RetryHelper.Execute(() => { modulesCollection = process.Modules; }, maxAttempts: 5, backoffFunc: null, retryWhen: e => e.GetType() == typeof(Win32Exception)); int expectedCount = 0; int disposedCount = 0; foreach (ProcessModule processModule in modulesCollection) { expectedCount += 1; processModule.Disposed += (_, __) => disposedCount += 1; } KillWait(process); Assert.Equal(0, disposedCount); process.Dispose(); Assert.Equal(expectedCount, disposedCount); }
internal static void AssertCacheSize(long size, MemoryCache cache) { // Size is only eventually consistent, so retry a few times RetryHelper.Execute(() => { Assert.Equal(size, cache.Size); }, maxAttempts: 12, (iteration) => (int)Math.Pow(2, iteration)); // 2ms, 4ms.. 4096 ms. In practice, retries are rarely needed. }
public async Task NonDisposedSocket_SafeHandlesCollected(bool clientAsync) { List <WeakReference> handles = await CreateHandlesAsync(clientAsync); RetryHelper.Execute(() => { GC.Collect(); Assert.Equal(0, handles.Count(h => h.IsAlive)); }); }
public static void Execute_Succeed() { // Arrange var options = new RetryOptions(); // Act var result = RetryHelper.Execute(options, () => true); // Assert Assert.Equal(result, 0); }
public async Task UsePollingFileWatcher_UseActivePolling_HasChanged_SymbolicLink_TargetChanged(bool useWildcard, bool linkWasBroken) { // Arrange using var rootOfFile = new TempDirectory(GetTestFilePath()); // Create file 2 first as we want to verify that the change is reported regardless of the timestamp being older. string file2Path = Path.Combine(rootOfFile.Path, GetTestFileName()); File.WriteAllText(file2Path, "v2.1"); string file1Path = Path.Combine(rootOfFile.Path, GetTestFileName()); if (!linkWasBroken) { await Task.Delay(1000); // Wait a second before writing again, see https://github.com/dotnet/runtime/issues/55951. File.WriteAllText(file1Path, "v1.1"); } using var rootOfLink = new TempDirectory(GetTestFilePath()); string linkName = GetTestFileName(); string linkPath = Path.Combine(rootOfLink.Path, linkName); File.CreateSymbolicLink(linkPath, file1Path); string filter = useWildcard ? "*" : linkName; using var provider = new PhysicalFileProvider(rootOfLink.Path) { UsePollingFileWatcher = true, UseActivePolling = true }; IChangeToken token = provider.Watch(filter); var tcs = new TaskCompletionSource <bool>(); token.RegisterChangeCallback(_ => { tcs.TrySetResult(true); }, null); var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30)); cts.Token.Register(() => tcs.TrySetCanceled()); // Act - Change link target to file 2. File.Delete(linkPath); RetryHelper.Execute(() => { File.CreateSymbolicLink(linkPath, file2Path); // can fail, presumably due to some latency of delete of linkPath }, maxAttempts: 10, retryWhen: e => e is UnauthorizedAccessException); // Assert - It should report the change regardless of the timestamp being older. Assert.True(await tcs.Task, $"Change event was not raised - current time: {DateTime.UtcNow:O}, file1 LastWriteTimeUtc: {File.GetLastWriteTimeUtc(file1Path):O}, file2 LastWriteTime: {File.GetLastWriteTimeUtc(file2Path):O}."); }
public async Task RegisterSubscriberIfNeeded() { await RetryHelper.Execute(async() => { using (var connection = new SqlConnection(_connectionString)) using (var command = new SqlCommand(RegisterSubscriberQuery, connection)) { command.Parameters.AddWithValue("@Name", _applicationName); await connection.OpenAsync(); await command.ExecuteNonQueryAsync(); } }, IsConnectionResiliencyException); }
public void Timer_ChangeToDelete_DoesntFire() { RetryHelper.Execute(() => { const int DueTime = 1000; var mres = new ManualResetEventSlim(); using (var t = new Timer(_ => mres.Set(), null, DueTime, -1)) { t.Change(Timeout.Infinite, Timeout.Infinite); Assert.False(mres.Wait(DueTime * 2)); } }); }
[OuterLoop] // Occasional failures: https://github.com/dotnet/runtime/issues/12339 public void EncryptDecrypt_Read() { string tmpFileName = Path.GetTempFileName(); string textContentToEncrypt = "Content to encrypt"; File.WriteAllText(tmpFileName, textContentToEncrypt); try { string fileContentRead = File.ReadAllText(tmpFileName); Assert.Equal(textContentToEncrypt, fileContentRead); EnsureEFSServiceStarted(); try { File.Encrypt(tmpFileName); } catch (IOException e) when(e.HResult == unchecked ((int)0x80070490) || (e.HResult == unchecked ((int)0x80071776))) { // Ignore ERROR_NOT_FOUND 1168 (0x490). It is reported when EFS is disabled by domain policy. // Ignore ERROR_NO_USER_KEYS (0x1776). This occurs when no user key exists to encrypt with. throw new SkipTestException($"Encrypt not available. Error 0x{e.HResult:X}"); } catch (IOException e) { _output.WriteLine($"Encrypt failed with {e.Message} 0x{e.HResult:X}"); LogEFSDiagnostics(); throw; } Assert.Equal(fileContentRead, File.ReadAllText(tmpFileName)); Assert.Equal(FileAttributes.Encrypted, (FileAttributes.Encrypted & File.GetAttributes(tmpFileName))); // Sometimes Decrypt will fail with, eg., // System.IO.IOException : The process cannot access the file '...' because it is being used by another process. // Assumption is that it just needs a little more time RetryHelper.Execute(() => { File.Decrypt(tmpFileName); }, maxAttempts: 30, backoffFunc: null, retryWhen: e => e.GetType() == typeof(IOException)); Assert.Equal(fileContentRead, File.ReadAllText(tmpFileName)); Assert.NotEqual(FileAttributes.Encrypted, (FileAttributes.Encrypted & File.GetAttributes(tmpFileName))); } finally { File.Delete(tmpFileName); } }
public static void Execute_RetryFails() { // Arrange var options = new RetryOptions() { MaxRetryCount = 1, RetryFails = true }; // Act Assert.Throws <TimeoutException>(() => RetryHelper.Execute(options, () => false)); // Assert }
public async Task AddLog(long eventId, string result) { if (result == null) { throw new ArgumentNullException(nameof(result)); } await RetryHelper.Execute(async() => { using (var connection = new SqlConnection(_connectionString)) using (var command = new SqlCommand(InsertLogQuery, connection)) { command.Parameters.AddWithValue("@EventId", eventId); command.Parameters.AddWithValue("@SubscriberName", _applicationName); command.Parameters.AddWithValue("@Result", result); await connection.OpenAsync(); await command.ExecuteNonQueryAsync(); } }, IsConnectionResiliencyException); }
public static void Execute_RetryTimeout() { // Arrange var options = new RetryOptions() { MaxRetryCount = 2, RetryTimeout = 0 }; var attempt = 0; // Act var result = RetryHelper.Execute(options, () => { attempt++; return(false); }); // Assert Assert.Equal(attempt, result); Assert.Equal(1, attempt); }
public static void Execute_MaxRetryCount() { // Arrange var options = new RetryOptions() { MaxRetryCount = RandomHelper.NextInt(g_random, 1, 5), RetryTimeout = 1000 }; var attempt = 0; // Act var result = RetryHelper.Execute(options, () => { attempt++; return(false); }); // Assert Assert.Equal(attempt, result); Assert.Equal(options.MaxRetryCount, attempt - 1); }
public override bool Remove(string key) { return(RetryHelper.Execute(Retry, () => Inner.Remove(key)) == 0); }
public override bool Increment(DataKey <long> datakey, long delta, TimeSpan validFor) { return(RetryHelper.Execute(Retry, () => Inner.Increment(datakey, delta, validFor)) == 0); }
public override bool Clear() { return(RetryHelper.Execute(Retry, () => Inner.Clear()) == 0); }
public async Task <Event[]> GetEvents() { return(await RetryHelper.Execute(async() => { using (var connection = new SqlConnection(_connectionString)) { await connection.OpenAsync(); using (var transaction = connection.BeginTransaction()) { try { long lastEventId; using (var lastEventIdCommand = new SqlCommand(LastEventIdQuery, connection, transaction)) { lastEventIdCommand.Parameters.AddWithValue("@Name", _applicationName); var lastEventIdCommandResult = await lastEventIdCommand.ExecuteScalarAsync(); if (lastEventIdCommandResult == null || lastEventIdCommandResult == DBNull.Value) { return new Event[0]; } lastEventId = Convert.ToInt64(lastEventIdCommandResult); } List <Event> eventList; using (var eventListCommand = new SqlCommand(EventListQuery, connection, transaction)) { eventListCommand.Parameters.AddWithValue("@Id", lastEventId); eventListCommand.Parameters.AddWithValue("@SubscriberName", _applicationName); using (var eventListReader = await eventListCommand.ExecuteReaderAsync()) { eventList = new List <Event>(); while (await eventListReader.ReadAsync()) { var id = eventListReader.GetInt32(0); var type = eventListReader.GetString(1); var body = eventListReader.GetString(2); var consistentHashKey = await eventListReader.IsDBNullAsync(3) ? null : eventListReader.GetString(3); eventList.Add(new Event(id, type, body, consistentHashKey, DateTime.UtcNow)); } } } if (eventList.Count > 0) { lastEventId = eventList.Max(i => i.Id); using (var updateLastEventIdCommand = new SqlCommand(UpdateLastEventIdQuery, connection, transaction)) { updateLastEventIdCommand.Parameters.AddWithValue("@LastReadEventId", lastEventId); updateLastEventIdCommand.Parameters.AddWithValue("@Name", _applicationName); await updateLastEventIdCommand.ExecuteNonQueryAsync(); } } using (var updateLastReadAtCommand = new SqlCommand(UpdateLastReadAtQuery, connection, transaction)) { updateLastReadAtCommand.Parameters.AddWithValue("@LastReadAt", DateTime.UtcNow); updateLastReadAtCommand.Parameters.AddWithValue("@Name", _applicationName); await updateLastReadAtCommand.ExecuteNonQueryAsync(); } transaction.Commit(); return eventList.ToArray(); } catch { try { transaction.Rollback(); } catch (InvalidOperationException) { } throw; } } } }, IsConnectionResiliencyException)); }
public override bool Store <T>(DataKey <T> datakey, TimeSpan validFor) { return(RetryHelper.Execute(Retry, () => Inner.Store(datakey, validFor)) == 0); }
public override bool Increment(DataKey <long> datakey, long delta, DateTime expiresAt) { return(RetryHelper.Execute(Retry, () => Inner.Increment(datakey, delta, expiresAt)) == 0); }
public Task <TResult> Execute <TResult>(Func <Task <TResult> > operation) { return(RetryHelper.Execute(operation, MaxDelay, MaxRetryCount, ShouldRetryOn)); }
public Task Execute(Func <Task> operation) { return(RetryHelper.Execute(operation, MaxDelay, MaxRetryCount, ShouldRetryOn)); }
public override bool Store <T>(DataKey <T> datakey) { return(RetryHelper.Execute(Retry, () => Inner.Store(datakey)) == 0); }
public override bool Store <T>(DataKey <T> datakey, DateTime expiresAt) { return(RetryHelper.Execute(Retry, () => Inner.Store(datakey, expiresAt)) == 0); }