Browse Source

Fix cross-thread exceptions when running PowerShell scripts with Add Package Reference dialog is open.

pull/15/head
Matt Ward 14 years ago
parent
commit
65baef9f19
  1. 2
      src/AddIns/Misc/PackageManagement/Project/PackageManagement.csproj
  2. 5
      src/AddIns/Misc/PackageManagement/Project/Src/AddPackageReferenceViewModel.cs
  3. 3
      src/AddIns/Misc/PackageManagement/Project/Src/IPackageManagementWorkbench.cs
  4. 11
      src/AddIns/Misc/PackageManagement/Project/Src/IThreadSafePackageManagementEvents.cs
  5. 3
      src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementViewModels.cs
  6. 9
      src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementWorkbench.cs
  7. 178
      src/AddIns/Misc/PackageManagement/Project/Src/ThreadSafePackageManagementEvents.cs
  8. 1
      src/AddIns/Misc/PackageManagement/Test/PackageManagement.Tests.csproj
  9. 27
      src/AddIns/Misc/PackageManagement/Test/Src/AddPackageReferenceViewModelTests.cs
  10. 9
      src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakePackageManagementEvents.cs
  11. 17
      src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakePackageManagementWorkbench.cs
  12. 408
      src/AddIns/Misc/PackageManagement/Test/Src/ThreadSafePackageManagementEventsTests.cs

2
src/AddIns/Misc/PackageManagement/Project/PackageManagement.csproj

@ -102,6 +102,7 @@ @@ -102,6 +102,7 @@
<Compile Include="Src\IPackageManagementProject.cs" />
<Compile Include="Src\IPackageManagementProjectFactory.cs" />
<Compile Include="Src\IPackageManagementWorkbench.cs" />
<Compile Include="Src\IThreadSafePackageManagementEvents.cs" />
<Compile Include="Src\PackageActionRunner.cs" />
<Compile Include="Src\PackageActionsToRun.cs" />
<Compile Include="Src\PackageFiles.cs" />
@ -245,6 +246,7 @@ @@ -245,6 +246,7 @@
<Compile Include="Src\EnvDTE\Project.cs" />
<Compile Include="Src\Scripting\RunPackageScriptsAction.cs" />
<Compile Include="Src\SolutionPackageRepository.cs" />
<Compile Include="Src\ThreadSafePackageManagementEvents.cs" />
<Compile Include="Src\UninstallPackageAction.cs" />
<Compile Include="Src\UpdatedPackagesViewModel.cs" />
<Compile Include="Src\PackageViewModel.cs" />

5
src/AddIns/Misc/PackageManagement/Project/Src/AddPackageReferenceViewModel.cs

@ -13,7 +13,7 @@ namespace ICSharpCode.PackageManagement @@ -13,7 +13,7 @@ namespace ICSharpCode.PackageManagement
public class AddPackageReferenceViewModel : ViewModelBase<AddPackageReferenceViewModel>, IDisposable
{
IPackageManagementSolution solution;
IPackageManagementEvents packageManagementEvents;
IThreadSafePackageManagementEvents packageManagementEvents;
ILicenseAcceptanceService licenseAcceptanceService;
string message;
bool hasError;
@ -21,7 +21,7 @@ namespace ICSharpCode.PackageManagement @@ -21,7 +21,7 @@ namespace ICSharpCode.PackageManagement
public AddPackageReferenceViewModel(
IPackageManagementSolution solution,
IRegisteredPackageRepositories registeredPackageRepositories,
IPackageManagementEvents packageManagementEvents,
IThreadSafePackageManagementEvents packageManagementEvents,
IPackageActionRunner actionRunner,
ILicenseAcceptanceService licenseAcceptanceService,
ITaskFactory taskFactory)
@ -62,6 +62,7 @@ namespace ICSharpCode.PackageManagement @@ -62,6 +62,7 @@ namespace ICSharpCode.PackageManagement
packageManagementEvents.AcceptLicenses -= AcceptLicenses;
packageManagementEvents.PackageOperationError -= PackageOperationError;
packageManagementEvents.PackageOperationsStarting -= PackageOperationsStarting;
packageManagementEvents.Dispose();
}
void PackageOperationError(object sender, PackageOperationExceptionEventArgs e)

3
src/AddIns/Misc/PackageManagement/Project/Src/IPackageManagementWorkbench.cs

@ -7,6 +7,9 @@ namespace ICSharpCode.PackageManagement @@ -7,6 +7,9 @@ namespace ICSharpCode.PackageManagement
{
public interface IPackageManagementWorkbench
{
bool InvokeRequired { get; }
void SafeThreadAsyncCall<A, B>(Action<A, B> method, A arg1, B arg2);
void CreateConsolePad();
}
}

11
src/AddIns/Misc/PackageManagement/Project/Src/IThreadSafePackageManagementEvents.cs

@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
namespace ICSharpCode.PackageManagement
{
public interface IThreadSafePackageManagementEvents : IPackageManagementEvents, IDisposable
{
}
}

3
src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementViewModels.cs

@ -27,11 +27,12 @@ namespace ICSharpCode.PackageManagement @@ -27,11 +27,12 @@ namespace ICSharpCode.PackageManagement
{
CreateRegisteredPackageRepositories();
CreateSolution();
var packageManagementEvents = new ThreadSafePackageManagementEvents(PackageManagementServices.PackageManagementEvents);
addPackageReferenceViewModel =
new AddPackageReferenceViewModel(
solution,
registeredPackageRepositories,
PackageManagementServices.PackageManagementEvents,
packageManagementEvents,
PackageManagementServices.PackageActionRunner,
new LicenseAcceptanceService(),
new PackageManagementTaskFactory());

9
src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementWorkbench.cs

@ -22,5 +22,14 @@ namespace ICSharpCode.PackageManagement @@ -22,5 +22,14 @@ namespace ICSharpCode.PackageManagement
// Force creation of view model.
object control = pad.PadContent.Control;
}
public bool InvokeRequired {
get { return WorkbenchSingleton.InvokeRequired; }
}
public void SafeThreadAsyncCall<A, B>(Action<A, B> method, A arg1, B arg2)
{
WorkbenchSingleton.SafeThreadAsyncCall<A, B>(method, arg1, arg2);
}
}
}

178
src/AddIns/Misc/PackageManagement/Project/Src/ThreadSafePackageManagementEvents.cs

@ -0,0 +1,178 @@ @@ -0,0 +1,178 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using NuGet;
namespace ICSharpCode.PackageManagement
{
public class ThreadSafePackageManagementEvents : IThreadSafePackageManagementEvents
{
IPackageManagementEvents unsafeEvents;
IPackageManagementWorkbench workbench;
public ThreadSafePackageManagementEvents(IPackageManagementEvents unsafeEvents)
: this(unsafeEvents, new PackageManagementWorkbench())
{
}
public ThreadSafePackageManagementEvents(
IPackageManagementEvents unsafeEvents,
IPackageManagementWorkbench workbench)
{
this.unsafeEvents = unsafeEvents;
this.workbench = workbench;
RegisterEventHandlers();
}
void RegisterEventHandlers()
{
unsafeEvents.PackageOperationsStarting += RaisePackageOperationStartingEventIfHasSubscribers;
unsafeEvents.PackageOperationError += RaisePackageOperationErrorEventIfHasSubscribers;
unsafeEvents.ParentPackageInstalled += RaiseParentPackageInstalledEventIfHasSubscribers;
unsafeEvents.ParentPackageUninstalled += RaiseParentPackageUninstalledEventIfHasSubscribers;
}
public void Dispose()
{
UnregisterEventHandlers();
}
void UnregisterEventHandlers()
{
unsafeEvents.PackageOperationsStarting -= RaisePackageOperationStartingEventIfHasSubscribers;
unsafeEvents.PackageOperationError -= RaisePackageOperationErrorEventIfHasSubscribers;
unsafeEvents.ParentPackageInstalled -= RaiseParentPackageInstalledEventIfHasSubscribers;
unsafeEvents.ParentPackageUninstalled -= RaiseParentPackageUninstalledEventIfHasSubscribers;
}
void RaisePackageOperationStartingEventIfHasSubscribers(object sender, EventArgs e)
{
if (PackageOperationsStarting != null) {
RaisePackageOperationStartingEvent(sender, e);
}
}
void RaisePackageOperationStartingEvent(object sender, EventArgs e)
{
if (InvokeRequired) {
Action<object, EventArgs> action = RaisePackageOperationStartingEvent;
SafeThreadAsyncCall(action, sender, e);
} else {
PackageOperationsStarting(sender, e);
}
}
bool InvokeRequired {
get { return workbench.InvokeRequired; }
}
void SafeThreadAsyncCall<A, B>(Action<A, B> method, A arg1, B arg2)
{
workbench.SafeThreadAsyncCall<A, B>(method, arg1, arg2);
}
public event EventHandler PackageOperationsStarting;
void RaisePackageOperationErrorEventIfHasSubscribers(object sender, PackageOperationExceptionEventArgs e)
{
if (PackageOperationError != null) {
RaisePackageOperationErrorEvent(sender, e);
}
}
void RaisePackageOperationErrorEvent(object sender, PackageOperationExceptionEventArgs e)
{
if (PackageOperationError != null) {
if (InvokeRequired) {
Action<object, PackageOperationExceptionEventArgs> action = RaisePackageOperationErrorEvent;
SafeThreadAsyncCall(action, sender, e);
} else {
PackageOperationError(sender, e);
}
}
}
public event EventHandler<PackageOperationExceptionEventArgs> PackageOperationError;
void RaiseParentPackageInstalledEventIfHasSubscribers(object sender, ParentPackageOperationEventArgs e)
{
if (ParentPackageInstalled != null) {
RaiseParentPackageInstalledEvent(sender, e);
}
}
void RaiseParentPackageInstalledEvent(object sender, ParentPackageOperationEventArgs e)
{
if (InvokeRequired) {
Action<object, ParentPackageOperationEventArgs> action = RaiseParentPackageInstalledEvent;
SafeThreadAsyncCall(action, sender, e);
} else {
ParentPackageInstalled(sender, e);
}
}
public event EventHandler<ParentPackageOperationEventArgs> ParentPackageInstalled;
void RaiseParentPackageUninstalledEventIfHasSubscribers(object sender, ParentPackageOperationEventArgs e)
{
if (ParentPackageUninstalled != null) {
RaiseParentPackageUninstalledEvent(sender, e);
}
}
void RaiseParentPackageUninstalledEvent(object sender, ParentPackageOperationEventArgs e)
{
if (InvokeRequired) {
Action<object, ParentPackageOperationEventArgs> action = RaiseParentPackageUninstalledEvent;
SafeThreadAsyncCall(action, sender, e);
} else {
ParentPackageUninstalled(sender, e);
}
}
public event EventHandler<ParentPackageOperationEventArgs> ParentPackageUninstalled;
public event EventHandler<AcceptLicensesEventArgs> AcceptLicenses {
add { unsafeEvents.AcceptLicenses += value; }
remove { unsafeEvents.AcceptLicenses -= value; }
}
public event EventHandler<PackageOperationMessageLoggedEventArgs> PackageOperationMessageLogged {
add { unsafeEvents.PackageOperationMessageLogged += value; }
remove { unsafeEvents.PackageOperationMessageLogged -= value; }
}
public void OnPackageOperationsStarting()
{
unsafeEvents.OnPackageOperationsStarting();
}
public void OnPackageOperationError(Exception ex)
{
unsafeEvents.OnPackageOperationError(ex);
}
public bool OnAcceptLicenses(IEnumerable<IPackage> packages)
{
return unsafeEvents.OnAcceptLicenses(packages);
}
public void OnParentPackageInstalled(IPackage package)
{
unsafeEvents.OnParentPackageInstalled(package);
}
public void OnParentPackageUninstalled(IPackage package)
{
unsafeEvents.OnParentPackageUninstalled(package);
}
public void OnPackageOperationMessageLogged(MessageLevel level, string message, params object[] args)
{
unsafeEvents.OnPackageOperationMessageLogged(level, message, args);
}
}
}

1
src/AddIns/Misc/PackageManagement/Test/PackageManagement.Tests.csproj

@ -199,6 +199,7 @@ @@ -199,6 +199,7 @@
<Compile Include="Src\Scripting\PackageUninstallScriptFileNameTests.cs" />
<Compile Include="Src\Scripting\RunPackageScriptsActionTests.cs" />
<Compile Include="Src\SolutionPackageRepositoryTests.cs" />
<Compile Include="Src\ThreadSafePackageManagementEventsTests.cs" />
<Compile Include="Src\UninstallPackageActionTests.cs" />
<Compile Include="Src\UpdatedPackagesViewModelTests.cs" />
<Compile Include="Src\PackageViewModelTests.cs" />

27
src/AddIns/Misc/PackageManagement/Test/Src/AddPackageReferenceViewModelTests.cs

@ -23,6 +23,7 @@ namespace PackageManagement.Tests @@ -23,6 +23,7 @@ namespace PackageManagement.Tests
FakeTaskFactory taskFactory;
List<FakePackage> packagesPassedToOnAcceptLicenses;
FakePackageActionRunner fakeActionRunner;
FakePackageManagementEvents fakeThreadSafeEvents;
void CreateSolution()
{
@ -38,8 +39,14 @@ namespace PackageManagement.Tests @@ -38,8 +39,14 @@ namespace PackageManagement.Tests
void CreateViewModel(FakePackageManagementSolution solution)
{
taskFactory = new FakeTaskFactory();
packageManagementEvents = new PackageManagementEvents();
var threadSafeEvents = new ThreadSafePackageManagementEvents(packageManagementEvents, new FakePackageManagementWorkbench());
CreateViewModel(fakeSolution, threadSafeEvents);
}
void CreateViewModel(FakePackageManagementSolution solution, IThreadSafePackageManagementEvents packageManagementEvents)
{
taskFactory = new FakeTaskFactory();
fakeLicenseAcceptanceSevice = new FakeLicenseAcceptanceService();
fakeActionRunner = new FakePackageActionRunner();
viewModel = new AddPackageReferenceViewModel(
@ -52,6 +59,13 @@ namespace PackageManagement.Tests @@ -52,6 +59,13 @@ namespace PackageManagement.Tests
taskFactory.ExecuteAllFakeTasks();
}
void CreateViewModelWithFakeThreadSafePackageManagementEvents()
{
CreateSolution();
fakeThreadSafeEvents = new FakePackageManagementEvents();
CreateViewModel(fakeSolution, fakeThreadSafeEvents);
}
List<string> RecordViewModelPropertiesChanged()
{
var propertyNamesChanged = new List<string>();
@ -345,5 +359,16 @@ namespace PackageManagement.Tests @@ -345,5 +359,16 @@ namespace PackageManagement.Tests
Assert.AreEqual("Test", viewModel.Message);
}
[Test]
public void Dispose_MethodCalled_DisposesThreadSafePackageManagementEvents()
{
CreateViewModelWithFakeThreadSafePackageManagementEvents();
viewModel.Dispose();
bool disposed = fakeThreadSafeEvents.IsDisposed;
Assert.IsTrue(disposed);
}
}
}

9
src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakePackageManagementEvents.cs

@ -8,7 +8,7 @@ using NuGet; @@ -8,7 +8,7 @@ using NuGet;
namespace PackageManagement.Tests.Helpers
{
public class FakePackageManagementEvents : IPackageManagementEvents
public class FakePackageManagementEvents : IThreadSafePackageManagementEvents
{
#pragma warning disable 0067
public event EventHandler PackageOperationsStarting;
@ -66,5 +66,12 @@ namespace PackageManagement.Tests.Helpers @@ -66,5 +66,12 @@ namespace PackageManagement.Tests.Helpers
MessageLevelPassedToOnPackageOperationMessageLogged = level;
FormattedStringPassedToOnPackageOperationMessageLogged = String.Format(message, args);
}
public bool IsDisposed;
public void Dispose()
{
IsDisposed = true;
}
}
}

17
src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakePackageManagementWorkbench.cs

@ -14,5 +14,22 @@ namespace PackageManagement.Tests.Helpers @@ -14,5 +14,22 @@ namespace PackageManagement.Tests.Helpers
{
IsCreateConsolePadCalled = true;
}
public bool InvokeRequiredReturnValue;
public bool InvokeRequired {
get { return InvokeRequiredReturnValue; }
}
public bool IsSafeThreadAsyncCallMade;
public object Arg1PassedToSafeThreadAsyncCall;
public object Arg2PassedToSafeThreadAsyncCall;
public void SafeThreadAsyncCall<A, B>(Action<A, B> method, A arg1, B arg2)
{
IsSafeThreadAsyncCallMade = true;
Arg1PassedToSafeThreadAsyncCall = arg1;
Arg2PassedToSafeThreadAsyncCall = arg2;
}
}
}

408
src/AddIns/Misc/PackageManagement/Test/Src/ThreadSafePackageManagementEventsTests.cs

@ -0,0 +1,408 @@ @@ -0,0 +1,408 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using ICSharpCode.PackageManagement;
using ICSharpCode.PackageManagement.Design;
using NuGet;
using NUnit.Framework;
using PackageManagement.Tests.Helpers;
namespace PackageManagement.Tests
{
[TestFixture]
public class ThreadSafePackageManagementEventsTests
{
ThreadSafePackageManagementEvents threadSafeEvents;
FakePackageManagementEvents fakeEvents;
FakePackageManagementWorkbench fakeWorkbench;
PackageManagementEvents unsafeEvents;
bool eventHandlerFired;
void CreateEvents()
{
fakeEvents = new FakePackageManagementEvents();
fakeWorkbench = new FakePackageManagementWorkbench();
threadSafeEvents = new ThreadSafePackageManagementEvents(fakeEvents, fakeWorkbench);
}
void CreateEventsWithRealPackageManagementEvents()
{
unsafeEvents = new PackageManagementEvents();
fakeWorkbench = new FakePackageManagementWorkbench();
threadSafeEvents = new ThreadSafePackageManagementEvents(unsafeEvents, fakeWorkbench);
}
void OnEventHandlerFired(object sender, EventArgs e)
{
eventHandlerFired = true;
}
[Test]
public void OnPackageOperationsStarting_NoInvokeRequired_NonThreadSafePackageOperationsStartingMethodCalled()
{
CreateEvents();
threadSafeEvents.OnPackageOperationsStarting();
Assert.IsTrue(fakeEvents.IsOnPackageOperationsStartingCalled);
}
[Test]
public void OnPackageOperationError_NoInvokeRequired_NonThreadSafeOnPackageOperationErrorMethodCalled()
{
CreateEvents();
var expectedException = new Exception("test");
threadSafeEvents.OnPackageOperationError(expectedException);
Exception exception = fakeEvents.ExceptionPassedToOnPackageOperationError;
Assert.AreEqual(expectedException, exception);
}
[Test]
public void OnAcceptLicenses_NoInvokeRequired_NonThreadSafeOnAcceptLicensesMethodCalled()
{
CreateEvents();
var expectedPackages = new List<IPackage>();
bool result = threadSafeEvents.OnAcceptLicenses(expectedPackages);
IEnumerable<IPackage> packages = fakeEvents.PackagesPassedToOnAcceptLicenses;
Assert.AreEqual(expectedPackages, packages);
}
[Test]
public void OnAcceptLicenses_NoInvokeRequired_NonThreadSafeOnAcceptLicensesMethodCalledAndReturnsResult()
{
CreateEvents();
fakeEvents.AcceptLicensesReturnValue = false;
bool result = threadSafeEvents.OnAcceptLicenses(null);
Assert.IsFalse(result);
}
[Test]
public void OnParentPackageInstalled_NoInvokeRequired_NonThreadSafeOnParentPackageInstalledMethodCalled()
{
CreateEvents();
var expectedPackage = new FakePackage();
threadSafeEvents.OnParentPackageInstalled(expectedPackage);
IPackage package = fakeEvents.PackagePassedToOnParentPackageInstalled;
Assert.AreEqual(expectedPackage, package);
}
[Test]
public void OnParentPackageUninstalled_NoInvokeRequired_NonThreadSafeOnParentPackageUninstalledMethodCalled()
{
CreateEvents();
var expectedPackage = new FakePackage();
threadSafeEvents.OnParentPackageUninstalled(expectedPackage);
IPackage package = fakeEvents.PackagePassedToOnParentPackageUninstalled;
Assert.AreEqual(expectedPackage, package);
}
[Test]
public void OnPackageOperationMessageLogged_NoInvokeRequired_NonThreadSafeOnPackageOperationMessageLoggedMethodCalled()
{
CreateEvents();
var messageLevel = MessageLevel.Warning;
string message = "abc {0}";
string arg = "test";
threadSafeEvents.OnPackageOperationMessageLogged(messageLevel, message, arg);
Assert.AreEqual(messageLevel, fakeEvents.MessageLevelPassedToOnPackageOperationMessageLogged);
Assert.AreEqual("abc test", fakeEvents.FormattedStringPassedToOnPackageOperationMessageLogged);
}
[Test]
public void AcceptLicenses_UnsafeEventFired_ThreadSafeEventFired()
{
CreateEventsWithRealPackageManagementEvents();
bool fired = false;
threadSafeEvents.AcceptLicenses += (sender, e) => fired = true;
unsafeEvents.OnAcceptLicenses(null);
Assert.IsTrue(fired);
}
[Test]
public void AcceptLicenses_UnsafeEventFiredAfterEventHandlerRemoved_ThreadSafeEventIsNotFired()
{
CreateEventsWithRealPackageManagementEvents();
eventHandlerFired = false;
threadSafeEvents.AcceptLicenses += OnEventHandlerFired;
threadSafeEvents.AcceptLicenses -= OnEventHandlerFired;
unsafeEvents.OnAcceptLicenses(null);
Assert.IsFalse(eventHandlerFired);
}
[Test]
public void PackageOperationsStarting_UnsafeEventFired_ThreadSafeEventFired()
{
CreateEventsWithRealPackageManagementEvents();
bool fired = false;
threadSafeEvents.PackageOperationsStarting += (sender, e) => fired = true;
unsafeEvents.OnPackageOperationsStarting();
Assert.IsTrue(fired);
}
[Test]
public void PackageOperationsStarting_UnsafeEventFiredAndInvokeRequired_ThreadSafeEventIsSafelyInvoked()
{
CreateEventsWithRealPackageManagementEvents();
fakeWorkbench.InvokeRequiredReturnValue = true;
threadSafeEvents.PackageOperationsStarting += OnEventHandlerFired;
unsafeEvents.OnPackageOperationsStarting();
Assert.IsTrue(fakeWorkbench.IsSafeThreadAsyncCallMade);
}
[Test]
public void PackageOperationsStarting_UnsafeEventFiredAndInvokeRequiredButNoEventHandlerRegistered_ThreadSafeEventIsNotInvoked()
{
CreateEventsWithRealPackageManagementEvents();
fakeWorkbench.InvokeRequiredReturnValue = true;
unsafeEvents.OnPackageOperationsStarting();
Assert.IsFalse(fakeWorkbench.IsSafeThreadAsyncCallMade);
}
[Test]
public void PackageOperationsStarting_UnsafeEventFiredAfterEventHandlerRemoved_ThreadSafeEventIsNotFired()
{
CreateEventsWithRealPackageManagementEvents();
eventHandlerFired = false;
threadSafeEvents.PackageOperationsStarting += OnEventHandlerFired;
threadSafeEvents.PackageOperationsStarting -= OnEventHandlerFired;
unsafeEvents.OnPackageOperationsStarting();
Assert.IsFalse(eventHandlerFired);
}
[Test]
public void PackageOperationError_UnsafeEventFired_ThreadSafeEventFired()
{
CreateEventsWithRealPackageManagementEvents();
bool fired = false;
threadSafeEvents.PackageOperationError += (sender, e) => fired = true;
unsafeEvents.OnPackageOperationError(null);
Assert.IsTrue(fired);
}
[Test]
public void PackageOperationError_UnsafeEventFiredAndInvokeRequired_ThreadSafeEventIsSafelyInvoked()
{
CreateEventsWithRealPackageManagementEvents();
fakeWorkbench.InvokeRequiredReturnValue = true;
threadSafeEvents.PackageOperationError += OnEventHandlerFired;
var expectedException = new Exception("Test");
unsafeEvents.OnPackageOperationError(expectedException);
var eventArgs = fakeWorkbench.Arg2PassedToSafeThreadAsyncCall as PackageOperationExceptionEventArgs;
Exception exception = eventArgs.Exception;
Assert.AreEqual(expectedException, exception);
}
[Test]
public void PackageOperationError_UnsafeEventFiredAndInvokeRequiredButNoEventHandlerRegistered_ThreadSafeEventIsNotInvoked()
{
CreateEventsWithRealPackageManagementEvents();
fakeWorkbench.InvokeRequiredReturnValue = true;
unsafeEvents.OnPackageOperationError(new Exception());
Assert.IsFalse(fakeWorkbench.IsSafeThreadAsyncCallMade);
}
[Test]
public void PackageOperationError_UnsafeEventFiredAfterEventHandlerRemoved_ThreadSafeEventIsNotFired()
{
CreateEventsWithRealPackageManagementEvents();
eventHandlerFired = false;
threadSafeEvents.PackageOperationError += OnEventHandlerFired;
threadSafeEvents.PackageOperationError -= OnEventHandlerFired;
unsafeEvents.OnPackageOperationError(null);
Assert.IsFalse(eventHandlerFired);
}
[Test]
public void ParentPackageInstalled_UnsafeEventFired_ThreadSafeEventFired()
{
CreateEventsWithRealPackageManagementEvents();
bool fired = false;
threadSafeEvents.ParentPackageInstalled += (sender, e) => fired = true;
unsafeEvents.OnParentPackageInstalled(null);
Assert.IsTrue(fired);
}
[Test]
public void ParentPackageInstalled_UnsafeEventFiredAndInvokeRequired_ThreadSafeEventIsSafelyInvoked()
{
CreateEventsWithRealPackageManagementEvents();
fakeWorkbench.InvokeRequiredReturnValue = true;
threadSafeEvents.ParentPackageInstalled += OnEventHandlerFired;
var expectedPackage = new FakePackage();
unsafeEvents.OnParentPackageInstalled(expectedPackage);
var eventArgs = fakeWorkbench.Arg2PassedToSafeThreadAsyncCall as ParentPackageOperationEventArgs;
IPackage package = eventArgs.Package;
Assert.AreEqual(expectedPackage, package);
}
[Test]
public void ParentPackageInstalled_UnsafeEventFiredAndInvokeRequiredButNoEventHandlerRegistered_ThreadSafeEventIsNotInvoked()
{
CreateEventsWithRealPackageManagementEvents();
fakeWorkbench.InvokeRequiredReturnValue = true;
unsafeEvents.OnParentPackageInstalled(new FakePackage());
Assert.IsFalse(fakeWorkbench.IsSafeThreadAsyncCallMade);
}
[Test]
public void ParentPackageInstalled_UnsafeEventFiredAfterEventHandlerRemoved_ThreadSafeEventIsNotFired()
{
CreateEventsWithRealPackageManagementEvents();
eventHandlerFired = false;
threadSafeEvents.ParentPackageInstalled += OnEventHandlerFired;
threadSafeEvents.ParentPackageInstalled -= OnEventHandlerFired;
unsafeEvents.OnParentPackageInstalled(null);
Assert.IsFalse(eventHandlerFired);
}
[Test]
public void ParentPackageUninstalled_UnsafeEventFired_ThreadSafeEventFired()
{
CreateEventsWithRealPackageManagementEvents();
bool fired = false;
threadSafeEvents.ParentPackageUninstalled += (sender, e) => fired = true;
unsafeEvents.OnParentPackageUninstalled(null);
Assert.IsTrue(fired);
}
[Test]
public void ParentPackageUninstalled_UnsafeEventFiredAndInvokeRequired_ThreadSafeEventIsSafelyInvoked()
{
CreateEventsWithRealPackageManagementEvents();
fakeWorkbench.InvokeRequiredReturnValue = true;
threadSafeEvents.ParentPackageUninstalled += OnEventHandlerFired;
var expectedPackage = new FakePackage();
unsafeEvents.OnParentPackageUninstalled(expectedPackage);
var eventArgs = fakeWorkbench.Arg2PassedToSafeThreadAsyncCall as ParentPackageOperationEventArgs;
IPackage package = eventArgs.Package;
Assert.AreEqual(expectedPackage, package);
}
[Test]
public void ParentPackageUninstalled_UnsafeEventFiredAndInvokeRequiredButNoEventHandlerRegistered_ThreadSafeEventIsNotInvoked()
{
CreateEventsWithRealPackageManagementEvents();
fakeWorkbench.InvokeRequiredReturnValue = true;
unsafeEvents.OnParentPackageUninstalled(new FakePackage());
Assert.IsFalse(fakeWorkbench.IsSafeThreadAsyncCallMade);
}
[Test]
public void ParentPackageUninstalled_UnsafeEventFiredAfterEventHandlerRemoved_ThreadSafeEventIsNotFired()
{
CreateEventsWithRealPackageManagementEvents();
eventHandlerFired = false;
threadSafeEvents.ParentPackageUninstalled += OnEventHandlerFired;
threadSafeEvents.ParentPackageUninstalled -= OnEventHandlerFired;
unsafeEvents.OnParentPackageUninstalled(null);
Assert.IsFalse(eventHandlerFired);
}
[Test]
public void PackageOperationMessageLogged_UnsafeEventFired_ThreadSafeEventFired()
{
CreateEventsWithRealPackageManagementEvents();
bool fired = false;
threadSafeEvents.PackageOperationMessageLogged += (sender, e) => fired = true;
unsafeEvents.OnPackageOperationMessageLogged(MessageLevel.Info, String.Empty, new object[0]);
Assert.IsTrue(fired);
}
[Test]
public void PackageOperationMessageLogged_UnsafeEventFiredAfterEventHandlerRemoved_ThreadSafeEventIsNotFired()
{
CreateEventsWithRealPackageManagementEvents();
eventHandlerFired = false;
threadSafeEvents.PackageOperationMessageLogged += OnEventHandlerFired;
threadSafeEvents.PackageOperationMessageLogged -= OnEventHandlerFired;
unsafeEvents.OnPackageOperationMessageLogged(MessageLevel.Info, String.Empty, new object[0]);
Assert.IsFalse(eventHandlerFired);
}
[Test]
public void Dispose_PackageOperationsStartingHandlerExistsAndThreadUnsafeEventFiredAfterDispose_ThreadSafeEventIsNotFired()
{
CreateEventsWithRealPackageManagementEvents();
eventHandlerFired = false;
threadSafeEvents.PackageOperationsStarting += OnEventHandlerFired;
threadSafeEvents.Dispose();
unsafeEvents.OnPackageOperationsStarting();
Assert.IsFalse(eventHandlerFired);
}
[Test]
public void Dispose_PackageOperationErrorHandlerExistsAndThreadUnsafeEventFiredAfterDispose_ThreadSafeEventIsNotFired()
{
CreateEventsWithRealPackageManagementEvents();
eventHandlerFired = false;
threadSafeEvents.PackageOperationError += OnEventHandlerFired;
threadSafeEvents.Dispose();
unsafeEvents.OnPackageOperationError(new Exception());
Assert.IsFalse(eventHandlerFired);
}
[Test]
public void Dispose_ParentPackageInstalledHandlerExistsAndThreadUnsafeEventFiredAfterDispose_ThreadSafeEventIsNotFired()
{
CreateEventsWithRealPackageManagementEvents();
eventHandlerFired = false;
threadSafeEvents.ParentPackageInstalled += OnEventHandlerFired;
threadSafeEvents.Dispose();
unsafeEvents.OnParentPackageInstalled(new FakePackage());
Assert.IsFalse(eventHandlerFired);
}
[Test]
public void Dispose_ParentParentPackageUninstalledHandlerExistsAndThreadUnsafeEventFiredAfterDispose_ThreadSafeEventIsNotFired()
{
CreateEventsWithRealPackageManagementEvents();
eventHandlerFired = false;
threadSafeEvents.ParentPackageUninstalled += OnEventHandlerFired;
threadSafeEvents.Dispose();
unsafeEvents.OnParentPackageUninstalled(new FakePackage());
Assert.IsFalse(eventHandlerFired);
}
}
}
Loading…
Cancel
Save