protected override async Task <Tuple <decimal, string> > InvokeTestAsync(ExceptionAggregator aggregator) { BenchmarkEventSource.Log.BenchmarkStart(this.DisplayName, TestCase.Iterations); //inject ITracer instance if test method defines single parameter of type ITracer var testMethodParams = TestMethod.GetParameters(); var hasTracerParam = (testMethodParams.Length == 1 && testMethodParams[0].ParameterType == typeof(ITracer)); var args = hasTracerParam ? new object[] { NullTracer.Instance } : null; //run the test once to make sure it's been jitted await new BenchmarkTestInvoker(Test, MessageBus, TestClass, ConstructorArguments, TestMethod, args, aggregator, CancellationTokenSource).RunAsync(); decimal executionTime = 0; //starting from 1 so that iteration number appears correctly in ETW log for (int i = 1; i <= TestCase.Iterations; i++) { if (TestCase.CollectGargage) { GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); } var stopwatchTracer = new StopwatchTracer(); BenchmarkEventSource.Log.BenchmarkIterationStart(i); var invokerTime = await new BenchmarkTestInvoker(Test, MessageBus, TestClass, ConstructorArguments, TestMethod, hasTracerParam ? new object[] { stopwatchTracer } : null, aggregator, CancellationTokenSource).RunAsync(); BenchmarkEventSource.Log.BenchmarkIterationStop(i); var stopwatchTime = stopwatchTracer.GetElapsed(); if (stopwatchTime.HasValue) { executionTime += stopwatchTime.Value; } else { executionTime += invokerTime; } } var message = new DiagnosticMessage("{0} , Iterations : {1} , TotalMilliseconds : {2}", this.DisplayName, TestCase.Iterations, executionTime * 1000); diagnosticMessageSink.OnMessage(message); BenchmarkEventSource.Log.BenchmarkStop(this.DisplayName, TestCase.Iterations); return(Tuple.Create(executionTime, string.Empty)); }
internal override async Task <object> Run(HttpContext context, Func <Type, object> resolve, TestTarget target) { var executeTestMethod = defaultExecuteTestMethod; var methodParameters = TestMethod.GetParameters(); var queryParameters = context.Request.Query; if (queryParameters.Keys.Any(p => methodParameters.Select(pp => pp.Name).Contains(p))) { executeTestMethod = BuildTestMethodExpression( TestMethod, methodParameters .Select(p => { var value = queryParameters[p.Name].FirstOrDefault() ?? p.DefaultValue; try { object castedValue; if (p.ParameterType.IsEnum && value != null) { castedValue = Enum.Parse(p.ParameterType, value.ToString(), true); } else { castedValue = Convert.ChangeType(value, p.ParameterType); } return(Expression.Constant(castedValue)); } catch (FormatException e) { throw new ParameterFormatException(p.Name, p.ParameterType, e); } })); } var testClassInstance = (T)resolve(typeof(T)); switch (testClassInstance) { case IParameterizedTestCases parameterizedTest: parameterizedTest.RegisterTestCasesTo(target.DependencyRegistry); break; } return(executeTestMethod(testClassInstance)); }
/// <summary> /// /// </summary> /// <param name="testCase"></param> /// <param name="displayName"></param> /// <param name="skipReason"></param> /// <param name="constructorArguments"></param> /// <param name="testMethodArguments"></param> /// <param name="messageBus"></param> /// <param name="aggregator"></param> /// <param name="cancellationTokenSource"></param> public ScenarioTestCaseRunner(IXunitTestCase testCase, string displayName, string skipReason, object[] constructorArguments, object[] testMethodArguments, IMessageBus messageBus, ExceptionAggregator aggregator, CancellationTokenSource cancellationTokenSource) : base(testCase, displayName, skipReason, constructorArguments, testMethodArguments, messageBus, aggregator, cancellationTokenSource) { DisplayName = displayName; SkipReason = skipReason; ConstructorArguments = constructorArguments; TestClass = base.TestCase.TestMethod.TestClass.Class.ToRuntimeType(); TestMethod = base.TestCase.Method.ToRuntimeMethod(); ParameterInfo[] parameters = TestMethod.GetParameters(); Type[] parameterTypes = new Type[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { parameterTypes[i] = parameters[i].ParameterType; } TestMethodArguments = Reflector.ConvertArguments(testMethodArguments, parameterTypes); }
/// <inheritdoc/> protected override async Task <decimal> InvokeTestMethodAsync(object testClassInstance) { var oldSyncContext = SynchronizationContext.Current; try { var asyncSyncContext = new AsyncTestSyncContext(oldSyncContext); SetSynchronizationContext(asyncSyncContext); Exception testException = null; await Aggregator.RunAsync( () => Timer.AggregateAsync( async() => { var parameterCount = TestMethod.GetParameters().Length; var valueCount = TestMethodArguments == null ? 0 : TestMethodArguments.Length; if (parameterCount != valueCount) { Aggregator.Add( new InvalidOperationException( $"The test method expected {parameterCount} parameter value{(parameterCount == 1 ? "" : "s")}," + $"but {valueCount} parameter value{(valueCount == 1 ? "" : "s")} {(valueCount == 1 ? "was" : "were")} provided.") ); } else { try { var result = TestMethod.Invoke(testClassInstance, TestMethodArguments); var task = result as Task; if (task != null) { await task; } else { var ex = await asyncSyncContext.WaitForCompletionAsync(); if (ex != null) { testException = ex; Aggregator.Add(ex); } } } catch (Exception ex) { testException = ex; throw; } } } ) ); if (testException != null) { var handleTestFailure = testClassInstance as INeedToKnowTestFailure; if (handleTestFailure != null) { await Aggregator.RunAsync( () => handleTestFailure.HandleFailureAsync(Test, testException)); } } } finally { SetSynchronizationContext(oldSyncContext); } return(Timer.Total); }
/// <summary> /// Initializes a new instance of the <see cref="MettleTestCaseRunner"/> class. /// </summary> /// <param name="testCase">The test case to be run.</param> /// <param name="displayName">The display name of the test case.</param> /// <param name="skipReason">The skip reason, if the test is to be skipped.</param> /// <param name="constructorArguments">The arguments to be passed to the test class constructor.</param> /// <param name="testMethodArguments">The arguments to be passed to the test method.</param> /// <param name="messageBus">The message bus to report run status to.</param> /// <param name="aggregator">The exception aggregator used to run code and collect exceptions.</param> /// <param name="cancellationTokenSource">The task cancellation token source, used to cancel the test run.</param> public MettleTestCaseRunner(IXunitTestCase testCase, string displayName, string skipReason, object[] constructorArguments, object[] testMethodArguments, IMessageBus messageBus, ExceptionAggregator aggregator, CancellationTokenSource cancellationTokenSource, IServiceProvider serviceProvider) : base(testCase, messageBus, aggregator, cancellationTokenSource) { DisplayName = displayName; SkipReason = skipReason; TestClass = TestCase.TestMethod.TestClass.Class.ToRuntimeType(); TestMethod = TestCase.Method.ToRuntimeMethod(); this.serviceProvider = serviceProvider; var ctor = TestClass.GetConstructors().FirstOrDefault(); var parameters = ctor.GetParameters(); Type[] parameterTypes; object[] args; if (constructorArguments != null || constructorArguments.Length > 0) { parameterTypes = new Type[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { parameterTypes[i] = parameters[i].ParameterType; } args = constructorArguments ?? Array.Empty <object>(); var ctorArgs = new object[parameters.Length]; Array.Copy(args, ctorArgs, args.Length); for (int i = 0; i < parameters.Length; i++) { var obj = ctorArgs[i]; if (obj == null) { obj = this.serviceProvider?.GetService(parameters[i].ParameterType); } ctorArgs[i] = obj; } ConstructorArguments = Reflector.ConvertArguments(ctorArgs, parameterTypes); } else { ConstructorArguments = constructorArguments; } parameters = TestMethod.GetParameters(); parameterTypes = new Type[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { parameterTypes[i] = parameters[i].ParameterType; } args = testMethodArguments ?? Array.Empty <object>(); if (parameters.Length != args.Length) { var methodArgs = new object[parameters.Length]; Array.Copy(args, methodArgs, args.Length); for (var i = 0; i < parameters.Length; i++) { var obj = methodArgs[i]; if (obj == null) { obj = this.serviceProvider?.GetService(parameters[i].ParameterType); } methodArgs[i] = obj; } args = methodArgs; } TestMethodArguments = Reflector.ConvertArguments(args, parameterTypes); }