Exemplo n.º 1
0
        /// <summary>
        /// Creates an asynchronous Task object that executes the given critical phase and optional phases in a background thread
        /// and invokes all other callbacks on the UI thread.
        /// </summary>
        /// <param name="cancellationToken"></param>
        /// <param name="beforeStart">Invoked on UI thread</param>
        /// <param name="criticalPhase">First phase to run.  Must succeed (by returning <c>true</c> and not throwing an exception) for the optional phases to run.  Invoked on the background thread.</param>
        /// <param name="optionalPhases">Collection of phases that can fail (by throwing an exception) without preventing subsequent phases from running.  Invoked on the background thread.</param>
        /// <param name="fail">Called if the operation is canceled or the critical phase throws an exception.  Invoked on the UI thread.</param>
        /// <param name="succeed">Called if the operation completes successfully without being canceled.  Invoked on the UI thread.</param>
        /// <returns>
        /// Task object that returns <c>false</c> if the operation was canceled by the user or
        /// the critical phase threw an exception; otherwise <c>true</c>.
        /// </returns>
        private Task <bool> CreateStageTask(CancellationToken cancellationToken, TaskStartedEventHandler beforeStart, CriticalPhase criticalPhase, IEnumerable <OptionalPhase> optionalPhases, ExceptionEventHandler fail, TaskSucceededEventHandler succeed)
        {
            var canContinue = CreateCanContinueFunc(cancellationToken);

            return(new TaskBuilder()
                   .OnThread(_callbackScheduler)
                   .CancelWith(cancellationToken)
                   .BeforeStart(beforeStart)
                   .Fail(fail)
                   .DoWork(delegate(IThreadInvoker invoker, CancellationToken token)
            {
                cancellationToken.Register(() => Logger.Warn("User canceled current operation"));

                if (criticalPhase())
                {
                    foreach (var phase in optionalPhases.TakeWhile(phase => canContinue()))
                    {
                        phase();
                    }

                    if (canContinue())
                    {
                        invoker.InvokeOnUIThreadAsync(_ => succeed());
                        return;
                    }
                }

                // TODO: How should we handle exceptions here?
                // The rest of the code assumes exceptions are being handled by the plugin runner.
                invoker.InvokeOnUIThreadAsync(_ => fail(new ExceptionEventArgs()));
            })
                   .Build()
                   );
        }
Exemplo n.º 2
0
        public Task <bool> CreateMetadataTask(CancellationToken cancellationToken, TaskStartedEventHandler start, ExceptionEventHandler fail, TaskSucceededEventHandler succeed, string mkvPath = null)
        {
            var token          = cancellationToken;
            var optionalPhases = new[] { CreateGetMetadataPhase(token), CreateAutoDetectPhase(token), CreateRenamePhase(token, mkvPath) };

            return(CreateStageTask(
                       token,
                       start,
                       () => true,
                       optionalPhases,
                       fail,
                       succeed
                       ));
        }
Exemplo n.º 3
0
        public void EventsOutOfSequence()
        {
            // Make sure that the registry key is no present so that we can set the verbosity.
            DeleteVerbosityKey();
            using (OleServiceProvider provider = new OleServiceProvider())
            {
                using (TaskProvider task = new TaskProvider(new ServiceProvider(provider)))
                {
                    IVsHierarchy        hierarchy  = MockFactories.HierarchyForLogger(provider);
                    IVsOutputWindowPane output     = MockFactories.OutputPaneWithStringFunctions();
                    BaseMock            mockOutput = (BaseMock)output;

                    // Create the logger and make sure that it points to the verbosity
                    IDELoggerProxy logger = new IDELoggerProxy(output, task, hierarchy);
                    logger.SetBuildVerbosityRegistryRoot(TestVerbosityRoot);

                    // Create the IEventSource that will be used to send messages to the logger
                    BaseMock mockSource = MockFactories.CreateMSBuildEventSource();

                    // Now initialize the logger.
                    logger.Initialize(mockSource as IEventSource);

                    // Verify that the logger has installed an event handler for messages and
                    // build events.
                    Assert.IsNotNull(mockSource["MessageRaised"]);
                    BuildMessageEventHandler messageHandler = (BuildMessageEventHandler)mockSource["MessageRaised"];
                    Assert.IsNotNull(mockSource["BuildStarted"]);
                    BuildStartedEventHandler buildStartedHandler = (BuildStartedEventHandler)mockSource["BuildStarted"];
                    Assert.IsNotNull(mockSource["BuildFinished"]);
                    BuildFinishedEventHandler buildFinishedHandler = (BuildFinishedEventHandler)mockSource["BuildFinished"];
                    Assert.IsNotNull(mockSource["TaskStarted"]);
                    TaskStartedEventHandler taskStartedHandler = (TaskStartedEventHandler)mockSource["TaskStarted"];
                    Assert.IsNotNull(mockSource["TaskFinished"]);
                    TaskFinishedEventHandler taskFinishedHandler = (TaskFinishedEventHandler)mockSource["TaskFinished"];

                    // Create the arguments for the events and the delegates.
                    BuildMessageEventArgs messageArgs = new BuildMessageEventArgs("Message", "help", "sender", MessageImportance.Normal);
                    SendEventFunction     sendMessage = delegate { messageHandler.Invoke(mockSource, messageArgs); };
                    //
                    BuildStartedEventArgs startBuildArgs = new BuildStartedEventArgs("Start Build", "help");
                    SendEventFunction     sendStartBuild = delegate { buildStartedHandler.Invoke(mockSource, startBuildArgs); };
                    //
                    BuildFinishedEventArgs finishBuildArgs = new BuildFinishedEventArgs("End Build", "help", true);
                    SendEventFunction      sendEndBuild    = delegate { buildFinishedHandler.Invoke(mockSource, finishBuildArgs); };
                    //
                    TaskStartedEventArgs startTaskArgs = new TaskStartedEventArgs("Start Task", null, null, null, null);
                    SendEventFunction    sendStartTask = delegate { taskStartedHandler.Invoke(mockSource, startTaskArgs); };
                    //
                    TaskFinishedEventArgs endTaskArgs = new TaskFinishedEventArgs("End Task", null, null, null, null, true);
                    SendEventFunction     sendEndTask = delegate { taskFinishedHandler.Invoke(mockSource, endTaskArgs); };

                    // Set the verbosity to Diagnostic so that all the messages are written.
                    logger.Verbosity = LoggerVerbosity.Diagnostic;

                    List <SendEventFunction>[] events = new List <SendEventFunction>[] {
                        new List <SendEventFunction>(new SendEventFunction[] { sendMessage, sendEndBuild, sendStartBuild }),
                        new List <SendEventFunction>(new SendEventFunction[] { sendStartBuild, sendEndTask, sendEndBuild, sendStartTask }),
                        new List <SendEventFunction>(new SendEventFunction[] { sendStartTask, sendStartBuild, sendEndTask, sendEndBuild }),
                        new List <SendEventFunction>(new SendEventFunction[] { sendEndBuild, sendStartTask, sendEndTask, sendStartBuild }),
                        new List <SendEventFunction>(new SendEventFunction[] { sendEndBuild, sendEndTask, sendStartTask, sendStartBuild }),
                        new List <SendEventFunction>(new SendEventFunction[] { sendEndTask, sendEndBuild, sendStartTask, sendStartBuild }),
                    };

                    // Call the functions. Note that here we don't check for the actual text printed on the output,
                    // but we simply verify that the logger can handle the events without exceptions.
                    foreach (List <SendEventFunction> sendFunctions in events)
                    {
                        output.Clear();
                        foreach (SendEventFunction func in sendFunctions)
                        {
                            func();
                        }
                    }
                }
            }
        }
Exemplo n.º 4
0
            /// <summary>
            /// Initialize the internal event source which is used to raise events on loggers registered to this submission
            /// </summary>
            private void InitializeInternalEventSource()
            {
                _anyEventHandler = new AnyEventHandler(RaiseAnyEvent);
                _buildFinishedEventHandler = new BuildFinishedEventHandler(RaiseBuildFinishedEvent);
                _buildStartedEventHandler = new BuildStartedEventHandler(RaiseBuildStartedEvent);
                _customBuildEventHandler = new CustomBuildEventHandler(RaiseCustomEvent);
                _buildErrorEventHandler = new BuildErrorEventHandler(RaiseErrorEvent);
                _buildMessageEventHandler = new BuildMessageEventHandler(RaiseMessageEvent);
                _projectFinishedEventHandler = new ProjectFinishedEventHandler(RaiseProjectFinishedEvent);
                _projectStartedEventHandler = new ProjectStartedEventHandler(RaiseProjectStartedEvent);
                _buildStatusEventHandler = new BuildStatusEventHandler(RaiseStatusEvent);
                _targetFinishedEventHandler = new TargetFinishedEventHandler(RaiseTargetFinishedEvent);
                _targetStartedEventHandler = new TargetStartedEventHandler(RaiseTargetStartedEvent);
                _taskFinishedEventHandler = new TaskFinishedEventHandler(RaiseTaskFinishedEvent);
                _taskStartedEventHandler = new TaskStartedEventHandler(RaiseTaskStartedEvent);
                _buildWarningEventHandler = new BuildWarningEventHandler(RaiseWarningEvent);

                _eventSourceForBuild.AnyEventRaised += _anyEventHandler;
                _eventSourceForBuild.BuildFinished += _buildFinishedEventHandler;
                _eventSourceForBuild.BuildStarted += _buildStartedEventHandler;
                _eventSourceForBuild.CustomEventRaised += _customBuildEventHandler;
                _eventSourceForBuild.ErrorRaised += _buildErrorEventHandler;
                _eventSourceForBuild.MessageRaised += _buildMessageEventHandler;
                _eventSourceForBuild.ProjectFinished += _projectFinishedEventHandler;
                _eventSourceForBuild.ProjectStarted += _projectStartedEventHandler;
                _eventSourceForBuild.StatusEventRaised += _buildStatusEventHandler;
                _eventSourceForBuild.TargetFinished += _targetFinishedEventHandler;
                _eventSourceForBuild.TargetStarted += _targetStartedEventHandler;
                _eventSourceForBuild.TaskFinished += _taskFinishedEventHandler;
                _eventSourceForBuild.TaskStarted += _taskStartedEventHandler;
                _eventSourceForBuild.WarningRaised += _buildWarningEventHandler;
            }
Exemplo n.º 5
0
        public void MessageFormattingTest()
        {
            // Make sure that the registry key is no present so that we can set the verbosity.
            DeleteVerbosityKey();

            using (OleServiceProvider provider = new OleServiceProvider())
            {
                using (TaskProvider task = new TaskProvider(new ServiceProvider(provider)))
                {
                    IVsHierarchy        hierarchy  = MockFactories.HierarchyForLogger(provider);
                    IVsOutputWindowPane output     = MockFactories.OutputPaneWithStringFunctions();
                    BaseMock            mockOutput = (BaseMock)output;

                    // Create the logger and make sure that it points to the verbosity
                    IDELoggerProxy logger = new IDELoggerProxy(output, task, hierarchy);
                    logger.SetBuildVerbosityRegistryRoot(TestVerbosityRoot);

                    // Create the IEventSource that will be used to send messages to the logger
                    BaseMock mockSource = MockFactories.CreateMSBuildEventSource();

                    // Now initialize the logger.
                    logger.Initialize(mockSource as IEventSource);

                    // Verify that the logger has installed an event handler for messages and
                    // build events.
                    Assert.IsNotNull(mockSource["MessageRaised"]);
                    BuildMessageEventHandler messageHandler = (BuildMessageEventHandler)mockSource["MessageRaised"];
                    Assert.IsNotNull(mockSource["BuildStarted"]);
                    BuildStartedEventHandler buildStartedHandler = (BuildStartedEventHandler)mockSource["BuildStarted"];
                    Assert.IsNotNull(mockSource["BuildFinished"]);
                    BuildFinishedEventHandler buildFinishedHandler = (BuildFinishedEventHandler)mockSource["BuildFinished"];
                    Assert.IsNotNull(mockSource["TaskStarted"]);
                    TaskStartedEventHandler taskStartedHandler = (TaskStartedEventHandler)mockSource["TaskStarted"];
                    Assert.IsNotNull(mockSource["TaskFinished"]);
                    TaskFinishedEventHandler taskFinishedHandler = (TaskFinishedEventHandler)mockSource["TaskFinished"];

                    // Set the verbosity to Diagnostic so that all the messages are written.
                    logger.Verbosity = LoggerVerbosity.Diagnostic;

                    // Create a message of the expected importance.
                    BuildMessageEventArgs message = new BuildMessageEventArgs("message", "help", "sender", MessageImportance.Normal);
                    messageHandler.Invoke(mockSource, message);

                    // Add a second message with null text.
                    message = new BuildMessageEventArgs(null, "help", "sender", MessageImportance.Normal);
                    messageHandler.Invoke(mockSource, message);

                    // Add another message with emty text.
                    message = new BuildMessageEventArgs(string.Empty, "help", "sender", MessageImportance.Normal);
                    messageHandler.Invoke(mockSource, message);
                    System.Windows.Forms.Application.DoEvents();

                    string expected = "message" + Environment.NewLine;
                    System.Text.StringBuilder builder = (System.Text.StringBuilder)mockOutput["StringBuilder"];
                    Assert.AreEqual(expected, builder.ToString(), false);

                    // Clean up the text.
                    output.Clear();

                    // Now verify the identation in case of start and end build events.
                    string startText   = "Test Started";
                    string messageText = "build message";
                    string endText     = "Test Finished";
                    BuildStartedEventArgs startBuildArgs = new BuildStartedEventArgs(startText, "help");
                    buildStartedHandler.Invoke(mockSource, startBuildArgs);
                    message = new BuildMessageEventArgs(messageText, "help", "sender", MessageImportance.Normal);
                    messageHandler.Invoke(mockSource, message);
                    BuildFinishedEventArgs finishBuildArgs = new BuildFinishedEventArgs(endText, "help", true);
                    buildFinishedHandler.Invoke(mockSource, finishBuildArgs);
                    System.Windows.Forms.Application.DoEvents();

                    // Get the text in the output pane.
                    builder  = (System.Text.StringBuilder)mockOutput["StringBuilder"];
                    expected = string.Format("{0}{1}{2}{1}{1}{3}{1}", startText, Environment.NewLine, messageText, endText);
                    Assert.AreEqual(expected, builder.ToString(), false);

                    // Clear the output and test the identation in case of start and end task.
                    output.Clear();
                    TaskStartedEventArgs startTaskArgs = new TaskStartedEventArgs(startText, null, null, null, null);
                    taskStartedHandler.Invoke(mockSource, startTaskArgs);
                    message = new BuildMessageEventArgs(messageText, "help", "sender", MessageImportance.Normal);
                    messageHandler.Invoke(mockSource, message);
                    TaskFinishedEventArgs endTaskArgs = new TaskFinishedEventArgs(endText, null, null, null, null, true);
                    taskFinishedHandler.Invoke(mockSource, endTaskArgs);
                    System.Windows.Forms.Application.DoEvents();

                    // Verify the text in the output pane.
                    expected = string.Format("{0}{1}\t{2}{1}{3}{1}", startText, Environment.NewLine, messageText, endText);
                    builder  = (System.Text.StringBuilder)mockOutput["StringBuilder"];
                    Assert.AreEqual(expected, builder.ToString(), false);
                }
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Creates an asynchronous Task object that executes the given critical phase and optional phases in a background thread
        /// and invokes all other callbacks on the UI thread.
        /// </summary>
        /// <param name="cancellationToken"></param>
        /// <param name="beforeStart">Invoked on UI thread</param>
        /// <param name="criticalPhase">First phase to run.  Must succeed (by returning <c>true</c> and not throwing an exception) for the optional phases to run.  Invoked on the background thread.</param>
        /// <param name="optionalPhases">Collection of phases that can fail (by throwing an exception) without preventing subsequent phases from running.  Invoked on the background thread.</param>
        /// <param name="fail">Called if the operation is canceled or the critical phase throws an exception.  Invoked on the UI thread.</param>
        /// <param name="succeed">Called if the operation completes successfully without being canceled.  Invoked on the UI thread.</param>
        /// <returns>
        /// Task object that returns <c>false</c> if the operation was canceled by the user or
        /// the critical phase threw an exception; otherwise <c>true</c>.
        /// </returns>
        private Task<bool> CreateStageTask(CancellationToken cancellationToken, TaskStartedEventHandler beforeStart, CriticalPhase criticalPhase, IEnumerable<OptionalPhase> optionalPhases, ExceptionEventHandler fail, TaskSucceededEventHandler succeed)
        {
            var canContinue = CreateCanContinueFunc(cancellationToken);
            return new TaskBuilder()
                .OnThread(_callbackScheduler)
                .CancelWith(cancellationToken)
                .BeforeStart(beforeStart)
                .Fail(fail)
                .DoWork(delegate(IThreadInvoker invoker, CancellationToken token)
                    {
                        cancellationToken.Register(() => Logger.Warn("User canceled current operation"));

                        if (criticalPhase())
                        {
                            foreach (var phase in optionalPhases.TakeWhile(phase => canContinue()))
                            {
                                phase();
                            }

                            if (canContinue())
                            {
                                invoker.InvokeOnUIThreadAsync(_ => succeed());
                                return;
                            }
                        }

                        // TODO: How should we handle exceptions here?
                        // The rest of the code assumes exceptions are being handled by the plugin runner.
                        invoker.InvokeOnUIThreadAsync(_ => fail(new ExceptionEventArgs()));
                    })
                .Build()
            ;
        }
Exemplo n.º 7
0
 public Task<bool> CreateMetadataTask(CancellationToken cancellationToken, TaskStartedEventHandler start, ExceptionEventHandler fail, TaskSucceededEventHandler succeed, string mkvPath = null)
 {
     var token = cancellationToken;
     var optionalPhases = new[] { CreateGetMetadataPhase(token), CreateAutoDetectPhase(token), CreateRenamePhase(token, mkvPath) };
     return CreateStageTask(
         token,
         start,
         () => true,
         optionalPhases,
         fail,
         succeed
     );
 }
Exemplo n.º 8
0
 /// <summary>
 /// Runs the specified action in the UI thread before invoking the main <see cref="DoWork"/> action.
 /// If the <c>BeforeStart </c>action fails, the <c>DoWork</c> action will not be run.
 /// </summary>
 /// <param name="beforeStart">Action to run on the UI thread</param>
 /// <returns>Reference to this <c>TaskBuilder</c></returns>
 public TaskBuilder BeforeStart(TaskStartedEventHandler beforeStart)
 {
     _beforeStart = beforeStart;
     return(this);
 }
Exemplo n.º 9
0
 /// <summary>
 /// Runs the specified action in the UI thread before invoking the main <see cref="DoWork"/> action.
 /// If the <c>BeforeStart </c>action fails, the <c>DoWork</c> action will not be run.
 /// </summary>
 /// <param name="beforeStart">Action to run on the UI thread</param>
 /// <returns>Reference to this <c>TaskBuilder</c></returns>
 public TaskBuilder BeforeStart(TaskStartedEventHandler beforeStart)
 {
     _beforeStart = beforeStart;
     return this;
 }