Add delay to File System watchers to prevent Calibre installation issue (#6821)

* add a separate task to dequeue and create an app on installation

* Added tests to validate the behavior of the event handler

* release unmanaged memory
This commit is contained in:
Alekhya
2020-09-25 10:36:38 -07:00
committed by GitHub
parent 9e1711cbb9
commit f61db8ed3f
5 changed files with 186 additions and 47 deletions

View File

@@ -0,0 +1,106 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Collections.Concurrent;
using Microsoft.Plugin.Program.Storage;
using NUnit.Framework;
namespace Microsoft.Plugin.Program.UnitTests.Storage
{
[TestFixture]
public class ConcurrentQueueEventHandlerTest
{
[TestCase]
public void EventHandlerMustReturnEmptyPathForEmptyQueue()
{
// Arrange
int dequeueDelay = 0;
ConcurrentQueue<string> eventHandlingQueue = new ConcurrentQueue<string>();
// Act
string appPath = EventHandler.GetAppPathFromQueue(eventHandlingQueue, dequeueDelay);
// Assert
Assert.IsEmpty(appPath);
}
[TestCase(1)]
[TestCase(10)]
public void EventHandlerMustReturnPathForConcurrentQueueWithSameFilePaths(int itemCount)
{
// Arrange
int dequeueDelay = 0;
string appPath = "appPath";
ConcurrentQueue<string> eventHandlingQueue = new ConcurrentQueue<string>();
for (int i = 0; i < itemCount; i++)
{
eventHandlingQueue.Enqueue(appPath);
}
// Act
string pathFromQueue = EventHandler.GetAppPathFromQueue(eventHandlingQueue, dequeueDelay);
// Assert
Assert.AreEqual(pathFromQueue, appPath);
Assert.AreEqual(eventHandlingQueue.Count, 0);
}
[TestCase(5)]
public void EventHandlerMustReturnPathAndRetainDifferentFilePathsInQueue(int itemCount)
{
// Arrange
int dequeueDelay = 0;
string firstAppPath = "appPath1";
string secondAppPath = "appPath2";
ConcurrentQueue<string> eventHandlingQueue = new ConcurrentQueue<string>();
for (int i = 0; i < itemCount; i++)
{
eventHandlingQueue.Enqueue(firstAppPath);
}
for (int i = 0; i < itemCount; i++)
{
eventHandlingQueue.Enqueue(secondAppPath);
}
// Act
string pathFromQueue = EventHandler.GetAppPathFromQueue(eventHandlingQueue, dequeueDelay);
// Assert
Assert.AreEqual(pathFromQueue, firstAppPath);
Assert.AreEqual(eventHandlingQueue.Count, itemCount);
}
[TestCase(5)]
public void EventHandlerMustReturnPathAndRetainAllPathsAfterEncounteringADifferentPath(int itemCount)
{
// Arrange
int dequeueDelay = 0;
string firstAppPath = "appPath1";
string secondAppPath = "appPath2";
ConcurrentQueue<string> eventHandlingQueue = new ConcurrentQueue<string>();
for (int i = 0; i < itemCount; i++)
{
eventHandlingQueue.Enqueue(firstAppPath);
}
for (int i = 0; i < itemCount; i++)
{
eventHandlingQueue.Enqueue(secondAppPath);
}
for (int i = 0; i < itemCount; i++)
{
eventHandlingQueue.Enqueue(firstAppPath);
}
// Act
string pathFromQueue = EventHandler.GetAppPathFromQueue(eventHandlingQueue, dequeueDelay);
// Assert
Assert.AreEqual(pathFromQueue, firstAppPath);
Assert.AreEqual(eventHandlingQueue.Count, itemCount * 2);
}
}
}

View File

@@ -199,26 +199,6 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage
Assert.IsFalse(win32ProgramRepository.Contains(olditem));
}
[TestCase("path.url")]
public void Win32ProgramRepositoryMustCallOnAppChangedForUrlAppsWhenChangedEventIsRaised(string path)
{
// Arrange
Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, new BinaryStorage<IList<Win32Program>>("Win32"), _settings, _pathsToWatch);
FileSystemEventArgs e = new FileSystemEventArgs(WatcherChangeTypes.Changed, "directory", path);
// File.ReadAllLines must be mocked for url applications
var mockFile = new Mock<IFileWrapper>();
mockFile.Setup(m => m.ReadAllLines(It.IsAny<string>())).Returns(new string[] { "URL=steam://rungameid/1258080", "IconFile=iconFile" });
Win32Program.FileWrapper = mockFile.Object;
// Act
_fileSystemMocks[0].Raise(m => m.Changed += null, e);
// Assert
Assert.AreEqual(win32ProgramRepository.Count(), 1);
Assert.AreEqual(win32ProgramRepository.ElementAt(0).AppType, Win32Program.ApplicationType.InternetShortcutApplication); // Internet Shortcut Application
}
[TestCase("path.url")]
public void Win32ProgramRepositoryMustNotCreateUrlAppWhenCreatedEventIsRaised(string path)
{
@@ -319,26 +299,6 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage
Assert.IsFalse(win32ProgramRepository.Contains(olditem));
}
[TestCase("path.lnk")]
public void Win32ProgramRepositoryMustCallOnAppCreatedForLnkAppsWhenCreatedEventIsRaised(string path)
{
// Arrange
Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, new BinaryStorage<IList<Win32Program>>("Win32"), _settings, _pathsToWatch);
FileSystemEventArgs e = new FileSystemEventArgs(WatcherChangeTypes.Created, "directory", path);
// ShellLinkHelper must be mocked for lnk applications
var mockShellLink = new Mock<IShellLinkHelper>();
mockShellLink.Setup(m => m.RetrieveTargetPath(It.IsAny<string>())).Returns(string.Empty);
Win32Program.Helper = mockShellLink.Object;
// Act
_fileSystemMocks[0].Raise(m => m.Created += null, e);
// Assert
Assert.AreEqual(win32ProgramRepository.Count(), 1);
Assert.AreEqual(win32ProgramRepository.ElementAt(0).AppType, Win32Program.ApplicationType.Win32Application);
}
[TestCase("directory", "path.lnk")]
public void Win32ProgramRepositoryMustCallOnAppDeletedForLnkAppsWhenDeletedEventIsRaised(string directory, string path)
{