private async Task TestLoadSmartDetectorSimple(Type smartDetectorType, string expectedTitle = "test test test") { SmartDetectorManifest manifest = new SmartDetectorManifest("3", "simple", "description", Version.Parse("1.0"), smartDetectorType.Assembly.GetName().Name, smartDetectorType.FullName, new List <ResourceType>() { ResourceType.Subscription }, new List <int> { 60 }); SmartDetectorPackage package = new SmartDetectorPackage(manifest, this.assemblies["3"]); await this.TestLoadSmartDetectorSimple(package, expectedTitle); }
private async Task TestLoadSmartDetectorSimple(Type smartDetectorType, string expectedTitle = "test test test") { SmartDetectorManifest manifest = new SmartDetectorManifest("3", "simple", "description", Version.Parse("1.0"), smartDetectorType.Assembly.GetName().Name, smartDetectorType.FullName, new List <ResourceType>() { ResourceType.Subscription }, new List <int> { 60 }, null, null); Dictionary <string, byte[]> packageContent = this.assemblies["3"]; packageContent["manifest.json"] = Encoding.ASCII.GetBytes(JsonConvert.SerializeObject(manifest)); SmartDetectorPackage package = new SmartDetectorPackage(packageContent); await this.TestLoadSmartDetectorSimple(package, expectedTitle); }
public async Task WhenLoadingSmartDetectorFromPackageThenItWorks() { // Create the detector package from the detector's folder (instead of from the current folder), // and check that it can be loaded correctly, with its dependencies. DirectoryInfo currentFolder = new DirectoryInfo(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)); string flavor = Path.Combine(currentFolder.Parent.Name, currentFolder.Name); while (currentFolder.Name.ToUpperInvariant() != "TEST") { currentFolder = currentFolder.Parent; } string packageFolder = Path.Combine(currentFolder.FullName, @"testSmartDetector\TestSmartDetectorLibrary\bin", flavor); SmartDetectorPackage package = SmartDetectorPackage.CreateFromFolder(packageFolder); await this.TestLoadSmartDetectorSimple(package, "test title - with dependency - [1,2,3]"); }
/// <summary> /// Reads a Smart Detector's package from the repository /// </summary> /// <param name="smartDetectorId">The Smart Detector's ID</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>A <see cref="Task{TResult}"/> returning the Smart Detector package</returns> public async Task <SmartDetectorPackage> ReadSmartDetectorPackageAsync(string smartDetectorId, CancellationToken cancellationToken) { this.tracer.TraceInformation($"Getting Smart Detector {smartDetectorId} package"); try { CloudBlob latestVersionSmartDetectorBlob = await this.GetLatestSmartDetectorBlobVersionAsync(smartDetectorId, cancellationToken); this.tracer.TraceInformation($"Last version Smart Detector BLOB is {latestVersionSmartDetectorBlob.Name}"); using (var blobMemoryStream = new MemoryStream()) { // Download the blob to a stream and generate the Smart Detector package from it await latestVersionSmartDetectorBlob.DownloadToStreamAsync(blobMemoryStream, cancellationToken); return(SmartDetectorPackage.CreateFromStream(blobMemoryStream, this.tracer)); } } catch (StorageException e) { throw new SmartDetectorRepositoryException("Failed to get Smart Detector package from storage", e); } }
private async Task TestLoadSmartDetectorSimple(SmartDetectorPackage package, string expectedTitle) { ISmartDetectorLoader loader = new SmartDetectorLoader(this.tempFolder, this.tracerMock.Object); ISmartDetector detector = loader.LoadSmartDetector(package); Assert.IsNotNull(detector, "Smart Detector is NULL"); var resource = new ResourceIdentifier(ResourceType.VirtualMachine, "someSubscription", "someGroup", "someVM"); var analysisRequest = new AnalysisRequest( new List <ResourceIdentifier> { resource }, TimeSpan.FromDays(1), null, new Mock <IAnalysisServicesFactory>().Object, new Mock <IStateRepository>().Object); List <Alert> alerts = await detector.AnalyzeResourcesAsync(analysisRequest, this.tracerMock.Object, default(CancellationToken)); Assert.AreEqual(1, alerts.Count, "Incorrect number of alerts returned"); Assert.AreEqual(expectedTitle, alerts.Single().Title, "Alert title is wrong"); Assert.AreEqual(resource, alerts.Single().ResourceIdentifier, "Alert resource identifier is wrong"); }
/// <summary> /// Loads the Smart Detector, runs it, and returns the generated alert presentations /// </summary> /// <param name="request">The Smart Detector request</param> /// <param name="cancellationToken">The cancellation token</param> /// <returns>A <see cref="Task{TResult}"/>, returning the list of Alerts presentations generated by the Smart Detector</returns> public async Task <List <ContractsAlert> > RunAsync(SmartDetectorExecutionRequest request, CancellationToken cancellationToken) { // Read the Smart Detector's package this.tracer.TraceInformation($"Loading Smart Detector package for Smart Detector ID {request.SmartDetectorId}"); SmartDetectorPackage smartDetectorPackage = await this.smartDetectorRepository.ReadSmartDetectorPackageAsync(request.SmartDetectorId, cancellationToken); SmartDetectorManifest smartDetectorManifest = smartDetectorPackage.Manifest; this.tracer.TraceInformation($"Read Smart Detector package, ID {smartDetectorManifest.Id}, Version {smartDetectorManifest.Version}"); // Load the Smart Detector ISmartDetector smartDetector = this.smartDetectorLoader.LoadSmartDetector(smartDetectorPackage); this.tracer.TraceInformation($"Smart Detector instance loaded successfully, ID {smartDetectorManifest.Id}"); // Get the resources on which to run the Smart Detector List <ResourceIdentifier> resources = await this.GetResourcesForSmartDetector(request.ResourceIds, smartDetectorManifest, cancellationToken); // Create state repository IStateRepository stateRepository = this.stateRepositoryFactory.Create(request.SmartDetectorId); // Run the Smart Detector this.tracer.TraceInformation($"Started running Smart Detector ID {smartDetectorManifest.Id}, Name {smartDetectorManifest.Name}"); List <Alert> alerts; try { var analysisRequest = new AnalysisRequest(resources, request.DataEndTime, request.Cadence, request.AlertRuleResourceId, this.analysisServicesFactory, stateRepository); alerts = await smartDetector.AnalyzeResourcesAsync(analysisRequest, this.tracer, cancellationToken); this.tracer.TraceInformation($"Completed running Smart Detector ID {smartDetectorManifest.Id}, Name {smartDetectorManifest.Name}, returning {alerts.Count} alerts"); } catch (Exception e) { this.tracer.TraceInformation($"Failed running Smart Detector ID {smartDetectorManifest.Id}, Name {smartDetectorManifest.Name}: {e.Message}"); throw new SmartDetectorCustomException(e.GetType().ToString(), e.Message, e.StackTrace); } // Verify that each alert belongs to one of the types declared in the Smart Detector manifest foreach (Alert alert in alerts) { if (!smartDetectorManifest.SupportedResourceTypes.Contains(alert.ResourceIdentifier.ResourceType)) { throw new UnidentifiedAlertResourceTypeException(alert.ResourceIdentifier); } } // Trace the number of alerts of each type foreach (var alertType in alerts.GroupBy(x => x.GetType().Name)) { this.tracer.TraceInformation($"Got {alertType.Count()} Alerts of type '{alertType.Key}'"); this.tracer.ReportMetric("AlertType", alertType.Count(), new Dictionary <string, string>() { { "AlertType", alertType.Key } }); } // Create results List <ContractsAlert> results = new List <ContractsAlert>(); foreach (var alert in alerts) { QueryRunInfo queryRunInfo = await this.queryRunInfoProvider.GetQueryRunInfoAsync(new List <ResourceIdentifier>() { alert.ResourceIdentifier }, cancellationToken); results.Add(alert.CreateContractsAlert(request, smartDetectorManifest.Name, queryRunInfo)); } this.tracer.TraceInformation($"Returning {results.Count} results"); return(results); }
private void TestInitialize(ResourceType requestResourceType, ResourceType smartDetectorResourceType) { this.testContainer = new UnityContainer(); this.testContainer.RegisterType <ISmartDetectorRunner, SmartDetectorRunner>(); this.testContainer.RegisterInstance(new Mock <IExtendedTracer>().Object); ResourceIdentifier resourceId; switch (requestResourceType) { case ResourceType.Subscription: resourceId = new ResourceIdentifier(requestResourceType, "subscriptionId", string.Empty, string.Empty); break; case ResourceType.ResourceGroup: resourceId = new ResourceIdentifier(requestResourceType, "subscriptionId", "resourceGroup", string.Empty); break; default: resourceId = new ResourceIdentifier(requestResourceType, "subscriptionId", "resourceGroup", "resourceName"); break; } this.resourceIds = new List <string>() { resourceId.ToResourceId() }; this.request = new SmartDetectorExecutionRequest { ResourceIds = this.resourceIds, Cadence = TimeSpan.FromDays(1), SmartDetectorId = "1" }; var smartDetectorManifest = new SmartDetectorManifest("1", "Test Smart Detector", "Test Smart Detector description", Version.Parse("1.0"), "assembly", "class", new List <ResourceType>() { smartDetectorResourceType }, new List <int> { 60 }, null); this.smartDetectorPackage = new SmartDetectorPackage(smartDetectorManifest, new Dictionary <string, byte[]> { ["TestSmartDetectorLibrary"] = Array.Empty <byte>() }); var smartDetectorRepositoryMock = new Mock <ISmartDetectorRepository>(); smartDetectorRepositoryMock .Setup(x => x.ReadSmartDetectorPackageAsync(It.IsAny <string>(), It.IsAny <CancellationToken>())) .ReturnsAsync(() => this.smartDetectorPackage); this.testContainer.RegisterInstance <ISmartDetectorRepository>(smartDetectorRepositoryMock.Object); this.testContainer.RegisterInstance <IInternalAnalysisServicesFactory>(new Mock <IInternalAnalysisServicesFactory>().Object); this.smartDetector = new TestSmartDetector { ExpectedResourceType = smartDetectorResourceType }; var smartDetectorLoaderMock = new Mock <ISmartDetectorLoader>(); smartDetectorLoaderMock .Setup(x => x.LoadSmartDetector(this.smartDetectorPackage)) .Returns(this.smartDetector); this.testContainer.RegisterInstance <ISmartDetectorLoader>(smartDetectorLoaderMock.Object); var azureResourceManagerClientMock = new Mock <IExtendedAzureResourceManagerClient>(); azureResourceManagerClientMock .Setup(x => x.GetAllResourceGroupsInSubscriptionAsync(It.IsAny <string>(), It.IsAny <CancellationToken>())) .ReturnsAsync((string subscriptionId, CancellationToken cancellationToken) => new List <ResourceIdentifier>() { new ResourceIdentifier(ResourceType.ResourceGroup, subscriptionId, "resourceGroupName", string.Empty) }); azureResourceManagerClientMock .Setup(x => x.GetAllResourcesInSubscriptionAsync(It.IsAny <string>(), It.IsAny <IEnumerable <ResourceType> >(), It.IsAny <CancellationToken>())) .ReturnsAsync((string subscriptionId, IEnumerable <ResourceType> resourceTypes, CancellationToken cancellationToken) => new List <ResourceIdentifier>() { new ResourceIdentifier(ResourceType.VirtualMachine, subscriptionId, "resourceGroupName", "resourceName") }); azureResourceManagerClientMock .Setup(x => x.GetAllResourcesInResourceGroupAsync(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <IEnumerable <ResourceType> >(), It.IsAny <CancellationToken>())) .ReturnsAsync((string subscriptionId, string resourceGroupName, IEnumerable <ResourceType> resourceTypes, CancellationToken cancellationToken) => new List <ResourceIdentifier>() { new ResourceIdentifier(ResourceType.VirtualMachine, subscriptionId, resourceGroupName, "resourceName") }); this.testContainer.RegisterInstance <IExtendedAzureResourceManagerClient>(azureResourceManagerClientMock.Object); this.testContainer.RegisterInstance <IQueryRunInfoProvider>(new Mock <IQueryRunInfoProvider>().Object); var stateRepositoryMock = new Mock <IStateRepository>(); var stateRepositoryFactoryMock = new Mock <IStateRepositoryFactory>(); stateRepositoryFactoryMock.Setup(m => m.Create(It.IsAny <string>(), It.IsAny <string>())).Returns(stateRepositoryMock.Object); this.testContainer.RegisterInstance <IStateRepositoryFactory>(stateRepositoryFactoryMock.Object); }
/// <summary> /// Loads a Smart Detector. /// This method load the Smart Detector's assembly into the current application domain, /// and creates the Smart Detector object using reflection. /// </summary> /// <param name="smartDetectorPackage">The Smart Detector package.</param> /// <returns>The Smart Detector object.</returns> /// <exception cref="SmartDetectorLoadException"> /// Thrown if an error occurred during the Smart Detector load (either due to assembly load /// error or failure to create the Smart Detector object). /// </exception> public ISmartDetector LoadSmartDetector(SmartDetectorPackage smartDetectorPackage) { SmartDetectorManifest smartDetectorManifest = smartDetectorPackage.Manifest; try { this.tracer.TraceInformation($"Read {smartDetectorPackage.Content.Count} assemblies for Smart Detector ID {smartDetectorManifest.Id}"); // Write all DLLs to the temp folder foreach (var assemblyNameAndBytes in smartDetectorPackage.Content) { string fileName = Path.Combine(this.tempFolder, assemblyNameAndBytes.Key); Directory.CreateDirectory(Directory.GetParent(fileName).FullName); File.WriteAllBytes(fileName, assemblyNameAndBytes.Value); } // Add assembly resolver, that uses the Smart Detector's assemblies AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => { this.tracer.TraceInformation($"Resolving assembly {args.Name} for Smart Detector ID {smartDetectorManifest.Id}"); return(this.LoadAssembly(args.Name)); }; // Load the main Smart Detector assembly Assembly mainSmartDetectorAssembly = this.LoadAssembly(smartDetectorManifest.AssemblyName); if (mainSmartDetectorAssembly == null) { throw new SmartDetectorLoadException($"Unable to find main Smart Detector assembly: {smartDetectorManifest.AssemblyName}"); } // Get the Smart Detector type from the assembly this.tracer.TraceInformation($"Creating Smart Detector for {smartDetectorManifest.Name}, version {smartDetectorManifest.Version}, using type {smartDetectorManifest.ClassName}"); Type smartDetectorType = mainSmartDetectorAssembly.GetType(smartDetectorManifest.ClassName); if (smartDetectorType == null) { throw new SmartDetectorLoadException($"Smart Detector type {smartDetectorManifest.ClassName} was not found in the main Smart Detector assembly {smartDetectorManifest.AssemblyName}"); } // Check if the type inherits from ISmartDetector if (!typeof(ISmartDetector).IsAssignableFrom(smartDetectorType)) { throw new SmartDetectorLoadException($"Smart Detector type {smartDetectorType.Name} does not extend ISmartDetector"); } // Check that type is not abstract if (smartDetectorType.IsAbstract) { throw new SmartDetectorLoadException($"Smart Detector type {smartDetectorType.Name} is abstract - a Smart Detector must be a concrete type"); } // Check that type is not generic if (smartDetectorType.IsGenericTypeDefinition) { throw new SmartDetectorLoadException($"Smart Detector type {smartDetectorType.Name} is generic - a Smart Detector must be a closed constructed type"); } // Check that type has a parameter-less constructor if (smartDetectorType.GetConstructor(Type.EmptyTypes) == null) { throw new SmartDetectorLoadException($"Smart Detector type {smartDetectorType.Name} does not have a public, parameter-less constructor"); } // Create the Smart Detector object ISmartDetector smartDetector = Activator.CreateInstance(smartDetectorType) as ISmartDetector; if (smartDetector == null) { throw new SmartDetectorLoadException($"Smart Detector {smartDetectorType.Name} failed to be created - instance is null"); } this.tracer.TraceInformation($"Successfully created Smart Detector of type {smartDetectorType.Name}"); return(smartDetector); } catch (Exception e) { this.tracer.TrackEvent( "FailedToLoadSmartDetector", properties: new Dictionary <string, string> { { "smartDetectorId", smartDetectorManifest.Id }, { "SmartDetectorName", smartDetectorManifest.Name }, { "ExceptionType", e.GetType().Name }, { "ExceptionMessage", e.Message }, }); throw new SmartDetectorLoadException($"Failed to load Smart Detector {smartDetectorManifest.Name}", e); } }
/// <summary> /// Raises the <see cref="Application.Startup" /> event. /// </summary> /// <param name="e">A <see cref="StartupEventArgs" /> that contains the event data.</param> protected override void OnStartup(StartupEventArgs e) { // Cleanup previous temp folders (that are at least 2 days old), and create a new temp folder FileSystemExtensions.CleanupTempFolders(TempSubFolderName, 48); tempFolder = FileSystemExtensions.CreateTempFolder(TempSubFolderName); NotificationService notificationService = new NotificationService(); ITracer consoleTracer = new ConsoleTracer(string.Empty); var smartDetectorLoader = new SmartDetectorLoader(tempFolder, consoleTracer); // *Temporary*: if package file path wasn't accepted, raise file selection window to allow package file selection. // This option should be removed before launching version for customers (bug for tracking: 1177247) string smartDetectorPackagePath = e.Args.Length != 1 ? GetSmartDetectorPackagePath() : Diagnostics.EnsureStringNotNullOrWhiteSpace(() => e.Args[0]); SmartDetectorPackage smartDetectorPackage; using (var fileStream = new FileStream(smartDetectorPackagePath, FileMode.Open)) { smartDetectorPackage = SmartDetectorPackage.CreateFromStream(fileStream); } try { SmartDetectorManifest smartDetectorManifest = smartDetectorPackage.Manifest; ISmartDetector detector = smartDetectorLoader.LoadSmartDetector(smartDetectorPackage); // Authenticate the user to Active Directory IAuthenticationServices authenticationServices = new AuthenticationServices(); authenticationServices.AuthenticateUserAsync().Wait(); ICredentialsFactory credentialsFactory = new ActiveDirectoryCredentialsFactory(authenticationServices); IHttpClientWrapper httpClientWrapper = new HttpClientWrapper(); IExtendedAzureResourceManagerClient azureResourceManagerClient = new ExtendedAzureResourceManagerClient(httpClientWrapper, credentialsFactory, consoleTracer); // Create analysis service factory IInternalAnalysisServicesFactory analysisServicesFactory = new AnalysisServicesFactory(consoleTracer, httpClientWrapper, credentialsFactory, azureResourceManagerClient); // Create state repository factory IStateRepositoryFactory stateRepositoryFactory = new EmulationStateRepositoryFactory(); // Load user settings var userSettings = UserSettings.LoadUserSettings(); // Create the detector runner IPageableLogArchive logArchive = new PageableLogArchive(smartDetectorManifest.Name); IEmulationSmartDetectorRunner smartDetectorRunner = new SmartDetectorRunner( detector, analysisServicesFactory, smartDetectorManifest, stateRepositoryFactory, azureResourceManagerClient, logArchive); // Create a Unity container with all the required models and view models registrations Container = new UnityContainer(); Container .RegisterInstance(notificationService) .RegisterInstance <ITracer>(consoleTracer) .RegisterInstance(new AlertsRepository()) .RegisterInstance(authenticationServices) .RegisterInstance(azureResourceManagerClient) .RegisterInstance(detector) .RegisterInstance(smartDetectorManifest) .RegisterInstance(analysisServicesFactory) .RegisterInstance(logArchive) .RegisterInstance(smartDetectorRunner) .RegisterInstance(stateRepositoryFactory) .RegisterInstance(userSettings); } catch (Exception exception) { var message = $"{exception.Message}. {Environment.NewLine}{exception.InnerException?.Message}"; MessageBox.Show(message); System.Diagnostics.Trace.WriteLine(message); Environment.Exit(1); } }
public void WhenCreatingPackageWithEmptyContentThenExceptionIsThrown() { var package = new SmartDetectorPackage(new ReadOnlyDictionary <string, byte[]>(new Dictionary <string, byte[]>())); }
public void WhenCreatingPackageWithNullContentThenExceptionIsThrown() { var package = new SmartDetectorPackage(null); }
public void WhenCreatingPackageWithValidValuesThenPackageIsCreated() { var package = new SmartDetectorPackage(GetDefaultPackageContent()); }
private void TestInitialize(ResourceType requestResourceType, ResourceType smartDetectorResourceType) { this.testContainer = new UnityContainer(); this.testContainer.RegisterType <ISmartDetectorRunner, SmartDetectorRunner>(); this.testContainer.RegisterInstance(new Mock <ITracer>().Object); ResourceIdentifier resourceId; switch (requestResourceType) { case ResourceType.Subscription: resourceId = new ResourceIdentifier(requestResourceType, "subscriptionId", string.Empty, string.Empty); break; case ResourceType.ResourceGroup: resourceId = new ResourceIdentifier(requestResourceType, "subscriptionId", "resourceGroup", string.Empty); break; default: resourceId = new ResourceIdentifier(requestResourceType, "subscriptionId", "resourceGroup", "resourceName"); break; } this.resourceIds = new List <string> { resourceId.ToResourceId() }; this.analysisRequest = new SmartDetectorAnalysisRequest { ResourceIds = this.resourceIds, Cadence = TimeSpan.FromDays(1), AlertRuleResourceId = "alertRule", SmartDetectorId = "1", DetectorParameters = new Dictionary <string, object> { { "param1", "value1" }, { "param2", 2 }, } }; this.alertResolutionCheckRequest = new ContractsAlertResolutionCheckRequest { OriginalAnalysisRequest = new SmartDetectorAnalysisRequest { ResourceIds = this.resourceIds, Cadence = TimeSpan.FromDays(1), AlertRuleResourceId = "alertRule", SmartDetectorId = "2", DetectorParameters = new Dictionary <string, object> { { "param1", "value1" }, { "param2", 2 }, } }, AlertCorrelationHash = "correlationHash", TargetResource = resourceId.ToResourceId(), AlertFireTime = new DateTime(1985, 7, 3) }; var smartDetectorManifest = new SmartDetectorManifest( "1", "Test Smart Detector", "Test Smart Detector description", Version.Parse("1.0"), "TestSmartDetectorLibrary", "class", new List <ResourceType>() { smartDetectorResourceType }, new List <int> { 60 }, null, null); this.smartDetectorPackage = new SmartDetectorPackage(new Dictionary <string, byte[]> { ["manifest.json"] = Encoding.ASCII.GetBytes(JsonConvert.SerializeObject(smartDetectorManifest)), ["TestSmartDetectorLibrary"] = Array.Empty <byte>(), }); var autoResolveSmartDetectorManifest = new SmartDetectorManifest( "2", "Test Auto Resolve Smart Detector", "Test Auto Resolve Smart Detector description", Version.Parse("1.0"), "TestSmartDetectorLibrary", "class", new List <ResourceType>() { smartDetectorResourceType }, new List <int> { 60 }, null, null); this.autoResolveSmartDetectorPackage = new SmartDetectorPackage(new Dictionary <string, byte[]> { ["manifest.json"] = Encoding.ASCII.GetBytes(JsonConvert.SerializeObject(autoResolveSmartDetectorManifest)), ["TestSmartDetectorLibrary"] = Array.Empty <byte>(), }); var smartDetectorRepositoryMock = new Mock <ISmartDetectorRepository>(); smartDetectorRepositoryMock .Setup(x => x.ReadSmartDetectorPackageAsync("1", It.IsAny <CancellationToken>())) .ReturnsAsync(() => this.smartDetectorPackage); smartDetectorRepositoryMock .Setup(x => x.ReadSmartDetectorPackageAsync("2", It.IsAny <CancellationToken>())) .ReturnsAsync(() => this.autoResolveSmartDetectorPackage); this.testContainer.RegisterInstance(smartDetectorRepositoryMock.Object); this.testContainer.RegisterInstance(new Mock <IInternalAnalysisServicesFactory>().Object); this.smartDetector = new TestSmartDetector { ExpectedResourceType = smartDetectorResourceType }; this.autoResolveSmartDetector = new TestAutoResolveSmartDetector { ExpectedResourceType = smartDetectorResourceType }; var smartDetectorLoaderMock = new Mock <ISmartDetectorLoader>(); smartDetectorLoaderMock .Setup(x => x.LoadSmartDetector(this.smartDetectorPackage)) .Returns(() => this.smartDetector); smartDetectorLoaderMock .Setup(x => x.LoadSmartDetector(this.autoResolveSmartDetectorPackage)) .Returns(() => this.autoResolveSmartDetector); this.testContainer.RegisterInstance(smartDetectorLoaderMock.Object); var azureResourceManagerClientMock = new Mock <IExtendedAzureResourceManagerClient>(); azureResourceManagerClientMock .Setup(x => x.GetAllResourceGroupsInSubscriptionAsync(It.IsAny <string>(), It.IsAny <CancellationToken>())) .ReturnsAsync((string subscriptionId, CancellationToken cancellationToken) => new List <ResourceIdentifier>() { new ResourceIdentifier(ResourceType.ResourceGroup, subscriptionId, "resourceGroupName", string.Empty) }); azureResourceManagerClientMock .Setup(x => x.GetAllResourcesInSubscriptionAsync(It.IsAny <string>(), It.IsAny <IEnumerable <ResourceType> >(), It.IsAny <CancellationToken>())) .ReturnsAsync((string subscriptionId, IEnumerable <ResourceType> resourceTypes, CancellationToken cancellationToken) => new List <ResourceIdentifier>() { new ResourceIdentifier(ResourceType.VirtualMachine, subscriptionId, "resourceGroupName", "resourceName") }); azureResourceManagerClientMock .Setup(x => x.GetAllResourcesInResourceGroupAsync(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <IEnumerable <ResourceType> >(), It.IsAny <CancellationToken>())) .ReturnsAsync((string subscriptionId, string resourceGroupName, IEnumerable <ResourceType> resourceTypes, CancellationToken cancellationToken) => new List <ResourceIdentifier>() { new ResourceIdentifier(ResourceType.VirtualMachine, subscriptionId, resourceGroupName, "resourceName") }); this.testContainer.RegisterInstance(azureResourceManagerClientMock.Object); this.stateRepository = new Dictionary <string, object>(); this.stateRepositoryMock = new Mock <IStateRepository>(); this.stateRepositoryMock .Setup(m => m.StoreStateAsync(It.IsAny <string>(), It.IsAny <object>(), It.IsAny <CancellationToken>())) .Callback <string, object, CancellationToken>((key, value, token) => this.stateRepository[key] = value) .Returns(Task.CompletedTask); this.stateRepositoryMock .Setup(m => m.GetStateAsync <ResolutionState>(It.IsAny <string>(), It.IsAny <CancellationToken>())) .Returns <string, CancellationToken>((key, token) => Task.FromResult((ResolutionState)(this.stateRepository.ContainsKey(key) ? this.stateRepository[key] : null))); this.stateRepositoryMock .Setup(m => m.DeleteStateAsync(It.IsAny <string>(), It.IsAny <CancellationToken>())) .Callback <string, CancellationToken>((key, token) => this.stateRepository.Remove(key)) .Returns(Task.CompletedTask); this.stateRepositoryFactoryMock = new Mock <IStateRepositoryFactory>(); this.stateRepositoryFactoryMock.Setup(m => m.Create(It.IsAny <string>(), It.IsAny <string>())).Returns(this.stateRepositoryMock.Object); this.testContainer.RegisterInstance(this.stateRepositoryFactoryMock.Object); }