Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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 }));
            }
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
 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));
            });
        }
Beispiel #8
0
        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}.");
        }
Beispiel #10
0
 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);
 }
Beispiel #11
0
 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));
         }
     });
 }
Beispiel #12
0
        [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);
            }
        }
Beispiel #13
0
        public static void Execute_RetryFails()
        {
            // Arrange
            var options = new RetryOptions()
            {
                MaxRetryCount = 1,
                RetryFails    = true
            };

            // Act
            Assert.Throws <TimeoutException>(() => RetryHelper.Execute(options, () => false));

            // Assert
        }
Beispiel #14
0
        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);
        }
Beispiel #15
0
        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);
        }
Beispiel #16
0
        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);
        }
Beispiel #17
0
 public override bool Remove(string key)
 {
     return(RetryHelper.Execute(Retry, () => Inner.Remove(key)) == 0);
 }
Beispiel #18
0
 public override bool Increment(DataKey <long> datakey, long delta, TimeSpan validFor)
 {
     return(RetryHelper.Execute(Retry, () => Inner.Increment(datakey, delta, validFor)) == 0);
 }
Beispiel #19
0
 public override bool Clear()
 {
     return(RetryHelper.Execute(Retry, () => Inner.Clear()) == 0);
 }
Beispiel #20
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));
        }
Beispiel #21
0
 public override bool Store <T>(DataKey <T> datakey, TimeSpan validFor)
 {
     return(RetryHelper.Execute(Retry, () => Inner.Store(datakey, validFor)) == 0);
 }
Beispiel #22
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));
 }
Beispiel #25
0
 public override bool Store <T>(DataKey <T> datakey)
 {
     return(RetryHelper.Execute(Retry, () => Inner.Store(datakey)) == 0);
 }
Beispiel #26
0
 public override bool Store <T>(DataKey <T> datakey, DateTime expiresAt)
 {
     return(RetryHelper.Execute(Retry, () => Inner.Store(datakey, expiresAt)) == 0);
 }