/// <summary> /// Starts a new thread task. /// </summary> /// <remarks> /// <para> /// There is no need to call <see cref="WatchTask" /> on the returned task. /// </para> /// </remarks> /// <param name="name">The name of the task, or null to create a new name based /// on the method associated with the action.</param> /// <param name="action">The action to perform.</param> /// <returns>The new thread task.</returns> /// <exception cref="ArgumentNullException">Thrown if <paramref name="action"/> is null.</exception> public static ThreadTask StartThreadTask(string name, GallioAction action) { ThreadTask task = CreateThreadTask(name, action); task.Start(); return(task); }
public AssertionFailure[] CaptureFailures(GallioAction action, AssertionFailureBehavior assertionFailureBehavior, bool captureExceptionAsAssertionFailure) { if (action == null) { throw new ArgumentNullException("action"); } Scope newScope = new Scope(this, assertionFailureBehavior); Scope oldScope = null; try { oldScope = Interlocked.Exchange(ref scope, newScope); return(newScope.CaptureFailures(action, captureExceptionAsAssertionFailure)); } finally { if (oldScope != null && Interlocked.CompareExchange(ref scope, oldScope, newScope) != newScope) { throw new NotSupportedException("The current implementation does not support capturing failures concurrently."); } } }
/// <summary> /// Performs an action as a new step within the current context and associates it /// with the specified code reference. Does not verify the outcome of the step. /// </summary> /// <remarks> /// <para> /// This method creates a new child context with a new nested <see cref="Model.Tree.TestStep" />, /// enters the child context, performs the action, then exits the child context. /// </para> /// <para> /// This method may be called recursively to create nested steps or concurrently /// to create parallel steps. /// </para> /// <para> /// This method does not verify that the test step completed successfully. Check the /// <see cref="TestContext.Outcome" /> of the test step or call <see cref="RunStepAndVerifyOutcome"/> /// to ensure that the expected outcome was obtained. /// </para> /// </remarks> /// <param name="name">The name of the step.</param> /// <param name="action">The action to perform.</param> /// <param name="timeout">The step execution timeout, or null if none.</param> /// <param name="isTestCase">True if the step represents an independent test case.</param> /// <param name="codeElement">The associated code element, or null if none.</param> /// <exception cref="ArgumentNullException">Thrown if <paramref name="name"/> or /// <paramref name="action"/> is null.</exception> /// <returns>The context of the step that ran.</returns> /// <exception cref="ArgumentException">Thrown if <paramref name="name"/> is the empty string.</exception> /// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="timeout"/> is negative.</exception> public TestContext RunStep(string name, GallioAction action, TimeSpan?timeout, bool isTestCase, ICodeElementInfo codeElement) { if (name == null) { throw new ArgumentNullException("name"); } if (action == null) { throw new ArgumentNullException("action"); } if (timeout.HasValue && timeout.Value.Ticks < 0) { throw new ArgumentOutOfRangeException("timeout", "Timeout must not be negative."); } TestContext childContext = StartChildStep(name, codeElement, isTestCase); TestOutcome outcome = TestOutcome.Error; try { childContext.LifecyclePhase = LifecyclePhases.Execute; using (childContext.Sandbox.StartTimer(timeout)) { outcome = childContext.Sandbox.Run(childContext.LogWriter, action, null); } } finally { childContext.FinishStep(outcome); } return(childContext); }
public AssertionFailure[] CaptureFailures(GallioAction action, bool captureExceptionAsAssertionFailure) { try { action(); } catch (ThreadAbortException) { throw; } catch (AssertionFailureException ex) { if (!ex.IsSilent) { SubmitFailure(ex.Failure, true); } } catch (TestException) { throw; } catch (Exception ex) { if (!captureExceptionAsAssertionFailure) { throw; } SubmitFailure(AssertionFailureBuilder.WrapExceptionAsAssertionFailure(ex), true); } return(GetSavedFailuresAsArray()); }
public GallioAction SyncPrepareNextAction() { GallioAction action = actionQueue.Dequeue(); actionsInProgress += 1; return(action); }
public void AutoExecute(TriggerEvent triggerEvent, GallioAction triggerAction, GallioAction cleanupAction) { if (triggerAction == null) { throw new ArgumentNullException("triggerAction"); } Finishing += (sender, e) => { if (IsTriggerEventSatisfied(triggerEvent)) { try { triggerAction(); } catch (Exception ex) { UnhandledExceptionPolicy.Report("An exception occurred while performing an auto-execute trigger action.", ex); } } if (cleanupAction != null) { try { cleanupAction(); } catch (Exception ex) { UnhandledExceptionPolicy.Report("An exception occurred while performing an auto-execute cleanup action.", ex); } } }; }
public void Register(string identifier, GallioAction action) { if (hooks.ContainsKey(identifier)) { throw new Exception("Identifier is not unique"); } hooks.Add(identifier, action); }
private static ThreadTask CreateSTAThread(GallioAction start) { var task = new ThreadTask("AutoCAD Command Runner", start) { ApartmentState = ApartmentState.STA }; return(task); }
private void AssertCopyToNotThrowException(GallioAction action, string failureMessage) { AssertionHelper.Explain(() => Assert.DoesNotThrow(() => action()), innerFailures => new AssertionFailureBuilder(failureMessage) .AddLabeledValue("Method", "CopyTo") .SetStackTrace(Context.GetStackTraceData()) .AddInnerFailures(innerFailures) .ToAssertionFailure()); }
/// <summary> /// Creates a task that will execute code within a new locally running thread. /// When the task terminates successfully, its result will contain the value <c>null</c>. /// </summary> /// <param name="name">The name of the task.</param> /// <param name="action">The action to perform within the thread.</param> /// <exception cref="ArgumentNullException">Thrown if <paramref name="name"/> /// or <paramref name="action"/> is null.</exception> public ThreadTask(string name, GallioAction action) : base(name) { if (action == null) { throw new ArgumentNullException("action"); } invoker = new Invoker(action); }
private void DoAsync(GallioAction action) { if (InvokeRequired) { SyncContext.Post(cb => action(), null); } else { action(); } }
/// <summary> /// Creates a test case with a delegate to execute as its main body. /// </summary> /// <param name="name">The test case name.</param> /// <param name="execute">The main body of the test case.</param> /// <exception cref="ArgumentNullException">Thrown if <paramref name="name"/> or <paramref name="execute"/> /// is null.</exception> public TestCase(string name, GallioAction execute) : base(name) { if (execute == null) { throw new ArgumentNullException("execute"); } this.execute = execute; Timeout = TestAssemblyExecutionParameters.DefaultTestCaseTimeout; }
/// <summary> /// Registers an action to perform around all other actions /// currently in the chain. The contained part of the chain /// is passed in as an action to the decorator that the decorator /// can choose to run (or not) as needed. /// </summary> /// <remarks> /// <para> /// The value of <see cref="Action" /> will be set to a new instance /// that performs the specified <paramref name="decorator"/> around /// the current <see cref="Action" />. /// </para> /// </remarks> /// <param name="decorator">The decorator to register.</param> /// <exception cref="ArgumentNullException">Thrown if <paramref name="decorator"/> is null.</exception> public void Around(ActionDecorator decorator) { if (decorator == null) { throw new ArgumentNullException("decorator"); } GallioAction innerAction = Action; action = () => decorator(innerAction); }
private void RunDeferredAction(ICodeElementInfo codeElement, GallioAction deferredAction) { try { deferredAction(); } catch (Exception ex) { GetTestModelBuilder().PublishExceptionAsAnnotation(codeElement, ex); } }
/// <summary> /// Creates a queued message sink. /// </summary> /// <param name="messageSink">The message sink to wrap.</param> /// <exception cref="ArgumentNullException">Thrown if <paramref name="messageSink"/> is null.</exception> public QueuedMessageSink(IMessageSink messageSink) { if (messageSink == null) { throw new ArgumentNullException("messageSink"); } this.messageSink = messageSink; asyncPublishLoop = AsyncPublishLoop; queue = new Queue <Message>(); }
private void AssertCopyToThrowException(GallioAction action, string failureMessage, string label, object value) { AssertionHelper.Explain(() => Assert.Throws <Exception>(() => action()), innerFailures => new AssertionFailureBuilder( "Expected the method to throw an exception " + failureMessage) .AddLabeledValue("Method", "CopyTo") .AddRawLabeledValue(label, value) .SetStackTrace(Context.GetStackTraceData()) .AddInnerFailures(innerFailures) .ToAssertionFailure()); }
public RetryRunner(int repeat, TimeSpan polling, TimeSpan timeout, GallioAction action, GallioFunc <bool> condition, string messageFormat, object[] messageArgs, IClock clock) { this.repeat = repeat; this.polling = polling; this.timeout = timeout; this.condition = condition; this.action = action; this.messageFormat = messageFormat; this.messageArgs = messageArgs; this.clock = clock; }
private static Exception InvokeAndCaptureException(GallioAction action) { try { action(); return(null); } catch (Exception ex) { return(ex); } }
/// <summary> /// Creates a new thread task but does not start it. /// </summary> /// <remarks> /// <para> /// There is no need to call <see cref="WatchTask" /> on the returned task. /// </para> /// </remarks> /// <param name="name">The name of the task, or null to create a new name based /// on the method associated with the action.</param> /// <param name="action">The action to perform.</param> /// <returns>The new thread task.</returns> /// <exception cref="ArgumentNullException">Thrown if <paramref name="action"/> is null.</exception> public static ThreadTask CreateThreadTask(string name, GallioAction action) { if (action == null) { throw new ArgumentNullException("action"); } var task = new TestEnvironmentAwareThreadTask(GetTaskName(name, action), action, null); WatchTask(task); return(task); }
public void Invoke() { GallioAction action = @delegate as GallioAction; if (action != null) { action(); } else { Result = ((GallioFunc <object>)@delegate)(); } }
public IRetryOptions DoBetween(GallioAction action) { if (this.action != null) { throw new InvalidOperationException("Expected the custom action to be specified only once."); } if (action == null) { throw new ArgumentNullException("action"); } this.action = action; return(this); }
/// <summary> /// Registers an action to perform before all other actions /// currently in the chain. /// </summary> /// <remarks> /// <para> /// The value of <see cref="Action" /> will be set to a new instance /// that performs the specified <paramref name="action"/> before /// the current <see cref="Action" />. /// </para> /// </remarks> /// <param name="action">The action to register.</param> /// <exception cref="ArgumentNullException">Thrown if <paramref name="action"/> is null.</exception> public void Before(GallioAction action) { if (action == null) { throw new ArgumentNullException("action"); } if (this.action == null) { this.action = action; } else { this.action = (GallioAction)Delegate.Combine(action, this.action); } }
/// <summary> /// Synchronizes an action. /// </summary> /// <param name="invoker">The invoker, such as a WinForms control.</param> /// <param name="action">The action.</param> /// <exception cref="Exception">The exception thrown by the action.</exception> public static void Invoke(ISynchronizeInvoke invoker, GallioAction action) { if (invoker.InvokeRequired) { Exception exception = (Exception)invoker.Invoke( new GallioFunc <GallioAction, Exception>(InvokeAndCaptureException), new object[] { action }); if (exception != null) { ExceptionUtils.RethrowWithNoStackTraceLoss(exception); } } else { action(); } }
/// <summary> /// Performs an action and combines the possible assertion failures /// that were observed within the block, into a single outer failure with /// a common explanation. /// </summary> /// <param name="action">The action to invoke.</param> /// <param name="assertionFailureBehavior">The assertion failure behavior to use while the action runs.</param> /// <param name="explanation">A function that takes an array of inner failures and /// returns a single outer failure with a common explanation.</param> /// <exception cref="ArgumentNullException">Thrown if <paramref name="action"/> is null.</exception> /// <exception cref="ArgumentNullException">Thrown if <paramref name="explanation"/> is null.</exception> public static void Explain(GallioAction action, AssertionFailureBehavior assertionFailureBehavior, AssertionFailureExplanation explanation) { if (action == null) { throw new ArgumentNullException("action"); } if (explanation == null) { throw new ArgumentNullException("explanation"); } Verify(() => { AssertionFailure[] failures = Eval(action, assertionFailureBehavior); return(failures.Length == 0 ? null : explanation(failures)); }); }
/// <inheritdoc /> public void SetFooter(GallioAction showFooter, GallioAction hideFooter) { lock (syncRoot) { if (footerVisible && this.hideFooter != null) { this.hideFooter(); } this.showFooter = showFooter; this.hideFooter = hideFooter; if (footerVisible && showFooter != null) { showFooter(); } } }
/// <inheritdoc /> public void AddDeferredAction(ICodeElementInfo codeElement, int order, GallioAction deferredAction) { if (codeElement == null) { throw new ArgumentNullException("codeElement"); } if (deferredAction == null) { throw new ArgumentNullException("deferredAction"); } if (deferredActions == null) { deferredActions = new List <Triple <ICodeElementInfo, int, GallioAction> >(); } deferredActions.Add(new Triple <ICodeElementInfo, int, GallioAction>(codeElement, order, deferredAction)); }
private static void Protect(GallioAction action, out Exception exception) { exception = null; ComRetryMessageFilter.Install(ComRetryTimeout); try { action(); } catch (Exception ex) { exception = ex; } finally { ComRetryMessageFilter.Uninstall(); } }
/// <summary> /// Verifies that a block of code does not throw an exception of any type. /// </summary> /// <remarks> /// <para> /// The purpose of this assertion is to improve the readability of tests /// that only verify that an exception was not thrown. Using this assertion /// makes a positive and explicit statement that not throwing an exception /// is itself the primary behavior that is being verified. /// </para> /// </remarks> /// <param name="action">The action delegate to evaluate.</param> /// <param name="messageFormat">The custom assertion message format, or null if none.</param> /// <param name="messageArgs">The custom assertion message arguments, or null if none.</param> /// <exception cref="ArgumentNullException">Thrown if <paramref name="action"/> is null.</exception> /// <exception cref="AssertionException">Thrown if the verification failed unless the current <see cref="AssertionContext.AssertionFailureBehavior" /> indicates otherwise.</exception> public static void DoesNotThrow(GallioAction action, string messageFormat, params object[] messageArgs) { if (action == null) { throw new ArgumentNullException("action"); } AssertionHelper.Verify(() => { try { AssertionContext context = AssertionContext.CurrentContext; if (context != null) { // We will intercept any assertion failure which could occur while the action is run, then report it // as is. The goal is to prevent zealous "Assert.DoesNotThrow" to report the failure a second time. // Basically, a failing assertion inside a DoesNotThrow action does not make Assert.DoesNotThrow // to fail redundantly. See issue 769 (http://code.google.com/p/mb-unit/issues/detail?id=769) AssertionFailure[] failures = context.CaptureFailures(action, AssertionFailureBehavior.Throw, false); if (failures.Length > 0) { return(failures[0]); } } else { action(); } return(null); } catch (Exception actualException) { return(new AssertionFailureBuilder("The block threw an exception but none was expected.") .SetMessage(messageFormat, messageArgs) .AddException(actualException) .ToAssertionFailure()); } }); }
/// <summary> /// Performs an action as a new step within the current context and associates it /// with the specified code reference. Verifies that the step produced the expected outcome. /// </summary> /// <remarks> /// <para> /// This method creates a new child context with a new nested <see cref="Model.Tree.TestStep" />, /// enters the child context, performs the action, then exits the child context. /// </para> /// <para> /// This method may be called recursively to create nested steps or concurrently /// to create parallel steps. /// </para> /// <para> /// This method verifies that the step produced the expected outcome. If a different outcome /// was obtained, then raises an assertion failure. /// </para> /// </remarks> /// <param name="name">The name of the step.</param> /// <param name="action">The action to perform.</param> /// <param name="timeout">The step execution timeout, or null if none.</param> /// <param name="isTestCase">True if the step represents an independent test case.</param> /// <param name="codeElement">The associated code element, or null if none.</param> /// <param name="expectedOutcome">The expected outcome of the step.</param> /// <exception cref="ArgumentNullException">Thrown if <paramref name="name"/> or /// <paramref name="action"/> is null.</exception> /// <returns>The context of the step that ran.</returns> /// <exception cref="ArgumentException">Thrown if <paramref name="name"/> is the empty string.</exception> /// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="timeout"/> is negative.</exception> /// <exception cref="AssertionFailureException">Thrown if the expected outcome was not obtained.</exception> public TestContext RunStepAndVerifyOutcome(string name, GallioAction action, TimeSpan?timeout, bool isTestCase, ICodeElementInfo codeElement, TestOutcome expectedOutcome) { TestContext childContext = RunStep(name, action, timeout, isTestCase, codeElement); AssertionHelper.Verify(() => { TestOutcome actualOutcome = childContext.Outcome; if (actualOutcome == expectedOutcome) { return(null); } return(new AssertionFailureBuilder("The test step did not produce the expected outcome.") .AddLabeledValue("Expected Outcome", expectedOutcome.ToString()) .AddLabeledValue("Actual Outcome", actualOutcome.ToString()) .ToAssertionFailure()); }); return(childContext); }
private static void Protect(GallioAction action) { Exception exception = null; if (Thread.CurrentThread.GetApartmentState() == ApartmentState.STA) { Protect(action, out exception); } else { var thread = new Thread(() => Protect(action, out exception)); thread.SetApartmentState(ApartmentState.STA); thread.Start(); thread.Join(); } if (exception != null) { throw new VisualStudioException("Could not perform the requested Visual Studio operation.", exception); } }