Example #1
0
        /// <summary>
        /// To the extent reasonably possible, this method resets the state of the test environment to the same state as
        /// it started, ensuring that tests running in sequence cannot influence the outcome of later tests.
        /// </summary>
        /// <remarks>
        /// <para>The test cleanup runs in two primary steps:</para>
        /// <list type="number">
        /// <item>Waiting for asynchronous operations started by the test to complete.</item>
        /// <item>Disposing of mutable resources created by the test.</item>
        /// <item>Clearing static state variables related to the use of MEF during a test.</item>
        /// </list>
        /// </remarks>
        public override void After(MethodInfo methodUnderTest)
        {
            var exportProvider = ExportProviderCache.ExportProviderForCleanup;

            try
            {
                var listenerProvider = exportProvider?.GetExportedValues <IAsynchronousOperationListenerProvider>().SingleOrDefault();
                if (listenerProvider != null)
                {
                    if (ForegroundThreadAffinitizedObject.CurrentForegroundThreadData.Kind != ForegroundThreadDataKind.Unknown)
                    {
                        // Immediately clear items from the foreground notification service for which cancellation is
                        // requested. This service maintains a queue separately from Tasks, and work items scheduled for
                        // execution after a delay are not immediately purged when cancellation is requested. This code
                        // instructs the service to walk the list of queued work items and immediately cancel and purge any
                        // which are already cancelled.
                        var foregroundNotificationService = exportProvider?.GetExportedValues <IForegroundNotificationService>().SingleOrDefault() as ForegroundNotificationService;
                        foregroundNotificationService?.ReleaseCancelledItems();
                    }

                    // Join remaining operations with a timeout
                    using (var timeoutTokenSource = new CancellationTokenSource(CleanupTimeout))
                    {
                        try
                        {
                            var waiter = ((AsynchronousOperationListenerProvider)listenerProvider).WaitAllDispatcherOperationAndTasksAsync();
                            waiter.JoinUsingDispatcher(timeoutTokenSource.Token);
                        }
                        catch (OperationCanceledException ex) when(timeoutTokenSource.IsCancellationRequested)
                        {
                            var messageBuilder = new StringBuilder("Failed to clean up listeners in a timely manner.");

                            foreach (var token in ((AsynchronousOperationListenerProvider)listenerProvider).GetTokens())
                            {
                                messageBuilder.AppendLine().Append($"  {token}");
                            }

                            throw new TimeoutException(messageBuilder.ToString(), ex);
                        }
                    }
                }
            }
            finally
            {
                // Dispose of the export provider, including calling Dispose for any IDisposable services created during
                // the test.
                exportProvider?.Dispose();

                // Replace hooks with ones that always throw exceptions. These hooks detect cases where code executing
                // after the end of a test attempts to create an ExportProvider.
                MefHostServices.HookServiceCreation(DenyMefHostServicesCreationBetweenTests);
                RoslynServices.HookHostServices(() => throw new InvalidOperationException("Cannot create host services after test tear down."));

                // Reset static state variables.
                DesktopMefHostServices.ResetHostServicesTestOnly();
                _hostServices = null;
                ExportProviderCache.SetEnabled_OnlyUseExportProviderAttributeCanCall(false);
            }
        }
Example #2
0
        public override void Before(MethodInfo methodUnderTest)
        {
            MefHostServices.HookServiceCreation(CreateMefHostServices);
            RoslynServices.HookHostServices(() => _remoteHostServices.Value);
            DesktopMefHostServices.ResetHostServicesTestOnly();

            // make sure we enable this for all unit tests
            AsynchronousOperationListenerProvider.Enable(enable: true, diagnostics: true);
            ExportProviderCache.SetEnabled_OnlyUseExportProviderAttributeCanCall(true);
        }
 public override void After(MethodInfo methodUnderTest)
 {
     base.After(methodUnderTest);
     DesktopMefHostServices.ResetHostServicesTestOnly();
 }
 public override void Before(MethodInfo methodUnderTest)
 {
     DesktopMefHostServices.ResetHostServicesTestOnly();
     base.Before(methodUnderTest);
 }