/// <summary> /// Entry point to test a Pulumi application. Deployment will /// instantiate a new stack instance based on the type passed as TStack /// type parameter. This method creates no real resources. /// Note: Currently, unit tests that call <see cref="TestAsync{TStack}"/> /// must run serially; parallel execution is not supported. /// </summary> /// <param name="mocks">Hooks to mock the engine calls.</param> /// <param name="options">Optional settings for the test run.</param> /// <typeparam name="TStack">The type of the stack to test.</typeparam> /// <returns>Test result containing created resources and errors, if any.</returns> public static async Task <ImmutableArray <Resource> > TestAsync <TStack>(IMocks mocks, TestOptions?options = null) where TStack : Stack, new() { var engine = new MockEngine(); var monitor = new MockMonitor(mocks); Deployment deployment; lock (_instanceLock) { if (_instance != null) { throw new NotSupportedException($"Multiple executions of {nameof(TestAsync)} must run serially. Please configure your unit test suite to run tests one-by-one."); } deployment = new Deployment(engine, monitor, options); Instance = new DeploymentInstance(deployment); } try { await deployment._runner.RunAsync <TStack>(); return(engine.Errors.Count switch { 1 => throw new RunException(engine.Errors.Single()), int v when v > 1 => throw new AggregateException(engine.Errors.Select(e => new RunException(e))), _ => monitor.Resources.ToImmutableArray() }); }
private static async Task <ImmutableArray <Resource> > TestAsync(IMocks mocks, Func <IRunner, Task <int> > runAsync, TestOptions?options = null) { var engine = new MockEngine(); var monitor = new MockMonitor(mocks); await CreateRunnerAndRunAsync(() => new Deployment(engine, monitor, options), runAsync).ConfigureAwait(false); return(engine.Errors.Count switch { 1 => throw new RunException(engine.Errors.Single()), var v when v > 1 => throw new AggregateException(engine.Errors.Select(e => new RunException(e))), _ => monitor.Resources.ToImmutableArray() });