public async Task AfterSubscribeMultiple_FindFiles_ReturnResult_ChangeFiles_ReturnUpdated(int inits, int changes, int searches) { var rng = new Random(); var tokenizer = new WhitespaceTokenizer(); var analyzer = new FileAnalyzer(tokenizer); Dictionary <string, List <string> > InitFolder(TempFolder folder, int count) { var folderContent = new Dictionary <string, List <string> >(); for (var i = 0; i < count; i++) { var guids = new List <string>(Generators.Generate(100, () => Guid.NewGuid().ToString())); var text = string.Join(' ', guids); var name = folder.CreateFile(() => text); folderContent[name] = guids; } return(folderContent); } using var tmp = new TempFolder(0); var content = InitFolder(tmp, inits); await analyzer.Subscribe(tmp.FolderPath); var keys = content.Keys.ToList(); var searchTasks = new Dictionary <string, Task <IEnumerable <string> > >(); var delayedSearchTasks = new Dictionary <string, Task <IEnumerable <string> > >(); for (var i = 0; i < searches; i++) { var key = keys[rng.Next(keys.Count)]; var values = content[key]; var query = values[rng.Next(values.Count)]; searchTasks[key] = Task.Run(() => analyzer.Search(query)); delayedSearchTasks[key] = Task.Run(async() => await analyzer.DelayedSearch(query)); } await Task.WhenAll(searchTasks.Values); await Task.WhenAll(delayedSearchTasks.Values); Assert.All(searchTasks, kv => { var(key, task) = kv; var result = task.Result.ToList(); if (result.Any()) { Assert.All(result, s => Assert.True(s.Equals(key, StringComparison.InvariantCultureIgnoreCase))); } }); Assert.All(delayedSearchTasks, kv => { var(key, task) = kv; var result = task.Result.ToList(); Assert.NotEmpty(result); Assert.All(result, s => Assert.True(s.Equals(key, StringComparison.InvariantCultureIgnoreCase))); }); SpinWait.SpinUntil(() => !analyzer.IsIndexing); var changedFiles = new Dictionary <string, List <string> >(); for (var i = 0; i < changes; i++) { var guids = new List <string>(Generators.Generate(100, () => Guid.NewGuid().ToString())); var text = string.Join(' ', guids); var key = keys[rng.Next(keys.Count)]; keys.Remove(key); changedFiles[key] = guids; tmp.ChangeFile(key, () => text); } await Task.Delay(10 *changes); SpinWait.SpinUntil(() => !analyzer.IsIndexing); keys = changedFiles.Keys.ToList(); searchTasks = new Dictionary <string, Task <IEnumerable <string> > >(); delayedSearchTasks = new Dictionary <string, Task <IEnumerable <string> > >(); for (var i = 0; i < searches; i++) { var key = keys[rng.Next(keys.Count)]; var values = changedFiles[key]; var query = values[rng.Next(values.Count)]; searchTasks[key] = Task.Run(() => analyzer.Search(query)); delayedSearchTasks[key] = Task.Run(async() => await analyzer.DelayedSearch(query)); } await Task.WhenAll(searchTasks.Values); await Task.WhenAll(delayedSearchTasks.Values); Assert.All(searchTasks, kv => { var(key, task) = kv; var result = task.Result.ToList(); if (result.Any()) { Assert.All(result, s => Assert.True(s.Equals(key, StringComparison.InvariantCultureIgnoreCase))); } }); Assert.All(delayedSearchTasks, kv => { var(key, task) = kv; var result = task.Result.ToList(); Assert.NotEmpty(result); Assert.All(result, s => Assert.True(s.Equals(key, StringComparison.InvariantCultureIgnoreCase))); }); }