public void WhenRunningSmartDetectorThenCancellationIsHandledGracefully() { // Notify the Smart Detector that it should get stuck and wait for cancellation this.smartDetector.ShouldStuck = true; // Run the Smart Detector asynchronously ISmartDetectorRunner runner = this.testContainer.Resolve <ISmartDetectorRunner>(); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); Task t = runner.RunAsync(this.request, true, cancellationTokenSource.Token); SpinWait.SpinUntil(() => this.smartDetector.IsRunning); // Cancel and wait for expected result cancellationTokenSource.Cancel(); try { t.Wait(TimeSpan.FromSeconds(10)); } catch (AggregateException e) { var ftrsde = e.InnerExceptions.Single() as FailedToRunSmartDetectorException; Assert.IsNotNull(ftrsde, $"Expected to get inner exception of type {typeof(FailedToRunSmartDetectorException).Name}"); Assert.IsNull(ftrsde.InnerException, "e.InnerException != null"); Assert.IsTrue(ftrsde.Message.Contains(typeof(TaskCanceledException).Name), "e.Message.Contains(typeof(TaskCanceledException).Name)"); Assert.IsTrue(this.smartDetector.WasCanceled, "The Smart Detector was not canceled!"); throw; } }
/// <summary> /// Run the Smart Detector, by delegating the call to the registered <see cref="ISmartDetectorRunner"/> /// </summary> /// <param name="request">The Smart Detector request</param> /// <param name="cancellationToken">The cancellation token</param> /// <returns>A <see cref="Task{TResult}"/>, returning the alerts presentations generated by the Smart Detector</returns> private static async Task <List <ContractsAlert> > RunSmartDetectorAsync(SmartDetectorExecutionRequest request, CancellationToken cancellationToken) { ISmartDetectorRunner smartDetectorRunner = container.Resolve <ISmartDetectorRunner>(); bool shouldDetectorTrace = bool.Parse(ConfigurationReader.ReadConfig("ShouldDetectorTrace", required: true)); return(await smartDetectorRunner.RunAsync(request, shouldDetectorTrace, cancellationToken)); }
public static async Task <HttpResponseMessage> RunAsync( [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "analyze")] HttpRequestMessage request, TraceWriter log, ExecutionContext context, CancellationToken cancellationToken) { using (IUnityContainer childContainer = Container.CreateChildContainer().WithTracer(log, true)) { // Create a tracer for this run (that will also log to the specified TraceWriter) IExtendedTracer tracer = childContainer.Resolve <IExtendedTracer>(); tracer.TraceInformation($"Analyze function request received with invocation Id {context.InvocationId}"); tracer.AddCustomProperty("FunctionName", context.FunctionName); tracer.AddCustomProperty("InvocationId", context.InvocationId.ToString("N", CultureInfo.InvariantCulture)); try { // Trace app counters (before analysis) tracer.TraceAppCounters(); // Read the request SmartDetectorExecutionRequest smartDetectorExecutionRequest = await request.Content.ReadAsAsync <SmartDetectorExecutionRequest>(cancellationToken); tracer.AddCustomProperty("SmartDetectorId", smartDetectorExecutionRequest.SmartDetectorId); tracer.TraceInformation($"Analyze request received: {JsonConvert.SerializeObject(smartDetectorExecutionRequest)}"); // Process the request ISmartDetectorRunner runner = childContainer.Resolve <ISmartDetectorRunner>(); bool shouldDetectorTrace = bool.Parse(ConfigurationReader.ReadConfig("ShouldDetectorTrace", required: true)); List <ContractsAlert> alertPresentations = await runner.RunAsync(smartDetectorExecutionRequest, shouldDetectorTrace, cancellationToken); tracer.TraceInformation($"Analyze completed, returning {alertPresentations.Count} Alerts"); // Create the response with StringContent to prevent Json from serializing to a string var response = request.CreateResponse(HttpStatusCode.OK); response.Content = new StringContent(JsonConvert.SerializeObject(alertPresentations), Encoding.UTF8, "application/json"); return(response); } catch (AnalysisFailedException afe) { // Handle the exception TopLevelExceptionHandler.TraceUnhandledException(afe, tracer, log); // Return error status return(request.CreateResponse(afe.StatusCode, afe.ReasonPhrase)); } catch (Exception e) { // Handle the exception TopLevelExceptionHandler.TraceUnhandledException(e, tracer, log); // Return error status return(request.CreateResponse(HttpStatusCode.InternalServerError, e.Message)); } finally { // Trace app counters (after analysis) tracer.TraceAppCounters(); } } }
public async Task WhenRunningSmartDetectorThenCustomExceptionsAreHandledCorrectly() { // Notify the Smart Detector that it should throw a custom exception this.smartDetector.ShouldThrowCustom = true; // Run the Smart Detector ISmartDetectorRunner runner = this.testContainer.Resolve <ISmartDetectorRunner>(); await runner.RunAsync(this.request, true, default(CancellationToken)); }
public async Task WhenRunningSmartDetectorThenTheCorrectAlertIsReturned() { // Run the Smart Detector and validate results ISmartDetectorRunner runner = this.testContainer.Resolve <ISmartDetectorRunner>(); List <ContractsAlert> contractsAlerts = await runner.RunAsync(this.request, true, default(CancellationToken)); Assert.IsNotNull(contractsAlerts, "Presentation list is null"); Assert.AreEqual(1, contractsAlerts.Count); Assert.AreEqual("Test title", contractsAlerts.Single().Title); }
public async Task WhenRunningSmartDetectorCheckResolutionThenCustomExceptionsAreHandledCorrectly() { // Initialize the resolution state this.InitializeResolutionState(); // Notify the Smart Detector that it should throw a custom exception this.autoResolveSmartDetector.ShouldThrowCustom = true; // Run the Smart Detector ISmartDetectorRunner runner = this.testContainer.Resolve <ISmartDetectorRunner>(); await runner.CheckResolutionAsync(this.alertResolutionCheckRequest, true, default(CancellationToken)); }
public async Task WhenRunningSmartDetectorCheckResolutionForNonSupportingDetectorThenExceptionIsThrown() { // Initialize the resolution state this.InitializeResolutionState(); // Set the detector to be non supporting this.alertResolutionCheckRequest.OriginalAnalysisRequest.SmartDetectorId = "1"; // Run the Smart Detector and validate results ISmartDetectorRunner runner = this.testContainer.Resolve <ISmartDetectorRunner>(); await runner.CheckResolutionAsync(this.alertResolutionCheckRequest, true, default(CancellationToken)); }
public async Task WhenRunningSmartDetectorAnalyzeItIsDisposedIfItImplementsIDisposable() { this.smartDetector = new DisposableTestSmartDetector { ExpectedResourceType = ResourceType.VirtualMachine }; // Run the Smart Detector ISmartDetectorRunner runner = this.testContainer.Resolve <ISmartDetectorRunner>(); await runner.AnalyzeAsync(this.analysisRequest, true, default(CancellationToken)); Assert.IsTrue(((DisposableTestSmartDetector)this.smartDetector).WasDisposed); }
public static async Task <HttpResponseMessage> RunAsync( [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "analyze")] HttpRequestMessage request, TraceWriter log, ExecutionContext context, CancellationToken cancellationToken) { using (IUnityContainer childContainer = Container.CreateChildContainer().WithTracer(log, true)) { // Create a tracer for this run (that will also log to the specified TraceWriter) ITracer tracer = childContainer.Resolve <ITracer>(); tracer.TraceInformation($"Analyze function request received with invocation Id {context.InvocationId}"); tracer.AddCustomProperty("FunctionName", context.FunctionName); tracer.AddCustomProperty("InvocationId", context.InvocationId.ToString("N")); try { // Trace app counters (before analysis) tracer.TraceAppCounters(); // Read the request SmartDetectorExecutionRequest smartDetectorExecutionRequest = await request.Content.ReadAsAsync <SmartDetectorExecutionRequest>(cancellationToken); tracer.AddCustomProperty("SmartDetectorId", smartDetectorExecutionRequest.SmartDetectorId); tracer.TraceInformation($"Analyze request received: {JsonConvert.SerializeObject(smartDetectorExecutionRequest)}"); // Process the request ISmartDetectorRunner runner = childContainer.Resolve <ISmartDetectorRunner>(); List <ContractsAlert> alertPresentations = await runner.RunAsync(smartDetectorExecutionRequest, cancellationToken); tracer.TraceInformation($"Analyze completed, returning {alertPresentations.Count} Alerts"); // Return the generated presentations return(request.CreateResponse(HttpStatusCode.OK, alertPresentations)); } catch (Exception e) { // Handle the exception TopLevelExceptionHandler.TraceUnhandledException(e, tracer, log); // Return error status return(request.CreateResponse(HttpStatusCode.InternalServerError, e.Message)); } finally { // Trace app counters (after analysis) tracer.TraceAppCounters(); } } }
public async Task WhenRunningSmartDetectorAnalyzeThenTheCorrectAlertIsReturned() { // Run the Smart Detector and validate results ISmartDetectorRunner runner = this.testContainer.Resolve <ISmartDetectorRunner>(); List <ContractsAlert> contractsAlerts = await runner.AnalyzeAsync(this.analysisRequest, true, default(CancellationToken)); Assert.IsNotNull(contractsAlerts, "Presentation list is null"); Assert.AreEqual(1, contractsAlerts.Count); Assert.AreEqual("Test title", contractsAlerts.Single().Title); Assert.IsNull(contractsAlerts.Single().ResolutionParameters); // Assert the detector's state Assert.AreEqual(1, this.stateRepository.Count); Assert.AreEqual("test state", this.stateRepository["test key"]); }
/// <summary> /// Run the Smart Detector, by delegating the call to the registered <see cref="ISmartDetectorRunner"/> /// </summary> /// <param name="request">The Smart Detector request</param> /// <param name="cancellationToken">The cancellation token</param> /// <returns>A <see cref="Task{TResult}"/>, returning the result of the call to the runner.</returns> private static async Task <object> RunSmartDetectorAsync(SmartDetectorRunnerChildProcessInput request, CancellationToken cancellationToken) { ISmartDetectorRunner smartDetectorRunner = container.Resolve <ISmartDetectorRunner>(); bool shouldDetectorTrace = bool.Parse(ConfigurationReader.ReadConfig("ShouldDetectorTrace", required: true)); if (request.AnalysisRequest != null) { return(await smartDetectorRunner.AnalyzeAsync(request.AnalysisRequest, shouldDetectorTrace, cancellationToken)); } else if (request.AlertResolutionCheckRequest != null) { return(await smartDetectorRunner.CheckResolutionAsync(request.AlertResolutionCheckRequest, shouldDetectorTrace, cancellationToken)); } throw new ArgumentException("Unable to determine flow to run for Smart Detector", nameof(request)); }
public async Task WhenRunningSmartDetectorCheckResolutionItIsDisposedIfItImplementsIDisposable() { // Initialize the resolution state this.InitializeResolutionState(); // Make the detector a disposable one this.autoResolveSmartDetector = new DisposableTestAutoResolveSmartDetector { ExpectedResourceType = ResourceType.VirtualMachine }; // Run the Smart Detector ISmartDetectorRunner runner = this.testContainer.Resolve <ISmartDetectorRunner>(); await runner.CheckResolutionAsync(this.alertResolutionCheckRequest, true, default(CancellationToken)); Assert.IsTrue(((DisposableTestAutoResolveSmartDetector)this.autoResolveSmartDetector).WasDisposed); }
public async Task WhenRunningSmartDetectorThenStateRepositoryIsCreatedAndPassedToSmartDetector() { // Setup mocks 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); // Run the Smart Detector ISmartDetectorRunner runner = this.testContainer.Resolve <ISmartDetectorRunner>(); List <ContractsAlert> contractsAlerts = await runner.RunAsync(this.request, true, default(CancellationToken)); // Assert stateRepositoryFactoryMock.Verify(m => m.Create(It.IsAny <string>(), It.IsAny <string>())); stateRepositoryMock.Verify(m => m.StoreStateAsync("test key", "test state", It.IsAny <CancellationToken>())); }
public async Task WhenRunningSmartDetectorThenExceptionsAreHandledCorrectly() { // Notify the Smart Detector that it should throw an exception this.smartDetector.ShouldThrow = true; // Run the Smart Detector ISmartDetectorRunner runner = this.testContainer.Resolve <ISmartDetectorRunner>(); try { await runner.RunAsync(this.request, default(CancellationToken)); } catch (SmartDetectorCustomException e) when(e.SmartDetectorExceptionType == typeof(DivideByZeroException).ToString()) { // Expected exception } }
public async Task WhenRunningSmartDetectorAnalyzeAndNotReadyExceptionIsThrownThenNoAlertsAreReturned() { // Setup the exception to throw this.smartDetector.ExceptionToThrow = new DetectorNotReadyException(); this.smartDetector.ShouldThrow = true; // Run the Smart Detector and validate results ISmartDetectorRunner runner = this.testContainer.Resolve <ISmartDetectorRunner>(); List <ContractsAlert> contractsAlerts = await runner.AnalyzeAsync(this.analysisRequest, true, default(CancellationToken)); Assert.IsNotNull(contractsAlerts, "Contract alerts list is null"); Assert.AreEqual(0, contractsAlerts.Count); // Assert the detector's state Assert.AreEqual(1, this.stateRepository.Count); Assert.AreEqual("test state", this.stateRepository["test key"]); }
public async Task WhenRunningSmartDetectorThenExceptionsAreHandledCorrectly() { // Notify the Smart Detector that it should throw an exception this.smartDetector.ShouldThrow = true; // Run the Smart Detector ISmartDetectorRunner runner = this.testContainer.Resolve <ISmartDetectorRunner>(); try { await runner.RunAsync(this.request, true, default(CancellationToken)); } catch (FailedToRunSmartDetectorException e) { // Expected exception Assert.IsNull(e.InnerException, "e.InnerException != null"); Assert.IsTrue(e.Message.Contains(typeof(DivideByZeroException).Name), "e.Message.Contains(typeof(DivideByZeroException).Name)"); throw; } }
public async Task WhenRunningSmartDetectorAnalyzeThenCancellationIsHandledGracefully() { // Notify the Smart Detector that it should get stuck and wait for cancellation this.smartDetector.ShouldStuck = true; // Run the Smart Detector asynchronously ISmartDetectorRunner runner = this.testContainer.Resolve <ISmartDetectorRunner>(); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); Task t = runner.AnalyzeAsync(this.analysisRequest, true, cancellationTokenSource.Token); SpinWait.SpinUntil(() => this.smartDetector.IsRunning); // Cancel and wait for expected result cancellationTokenSource.Cancel(); FailedToRunSmartDetectorException ex = await Assert.ThrowsExceptionAsync <FailedToRunSmartDetectorException>(() => t); Assert.IsNull(ex.InnerException, "e.InnerException != null"); Assert.IsTrue(ex.Message.Contains(typeof(TaskCanceledException).Name), "e.Message.Contains(typeof(TaskCanceledException).Name)"); Assert.IsTrue(this.smartDetector.WasCanceled, "The Smart Detector was not canceled!"); }
public async Task WhenRunningSmartDetectorCheckResolutionAndAlertIsResolvedThenTheCorrectResponseIsReturned() { // Initialize the resolution state this.InitializeResolutionState(); // Setup the detector to resolve the alert this.autoResolveSmartDetector.ShouldResolve = true; // Run the Smart Detector and validate results ISmartDetectorRunner runner = this.testContainer.Resolve <ISmartDetectorRunner>(); ContractsAlertResolutionCheckResponse alertResolutionCheckResponse = await runner.CheckResolutionAsync(this.alertResolutionCheckRequest, true, default(CancellationToken)); Assert.IsTrue(alertResolutionCheckResponse.ShouldBeResolved); Assert.IsNull(alertResolutionCheckResponse.ResolutionParameters); // Assert the detector's state Assert.AreEqual(1, this.stateRepository.Count); Assert.AreEqual("test state", this.stateRepository["test auto resolve key"]); }
public void WhenRunningSmartDetectorThenCancellationIsHandledGracefully() { // Notify the Smart Detector that it should get stuck and wait for cancellation this.smartDetector.ShouldStuck = true; // Run the Smart Detector asynchronously ISmartDetectorRunner runner = this.testContainer.Resolve <ISmartDetectorRunner>(); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); Task t = runner.RunAsync(this.request, cancellationTokenSource.Token); SpinWait.SpinUntil(() => this.smartDetector.IsRunning); // Cancel and wait for expected result cancellationTokenSource.Cancel(); try { t.Wait(TimeSpan.FromSeconds(10)); } catch (AggregateException e) when((e.InnerExceptions.Single() as SmartDetectorCustomException).SmartDetectorExceptionType == typeof(TaskCanceledException).ToString()) { Assert.IsTrue(this.smartDetector.WasCanceled, "The Smart Detector was not canceled!"); } }
public async Task WhenRunningSmartDetectorAnalyzeWithResolutionForSupportingDetectorThenTheCorrectAlertIsReturned() { this.autoResolveSmartDetector.ShouldAutoResolve = true; this.analysisRequest.SmartDetectorId = "2"; // Run the Smart Detector and validate results ISmartDetectorRunner runner = this.testContainer.Resolve <ISmartDetectorRunner>(); List <ContractsAlert> contractsAlerts = await runner.AnalyzeAsync(this.analysisRequest, true, default(CancellationToken)); Assert.IsNotNull(contractsAlerts, "Presentation list is null"); Assert.AreEqual(1, contractsAlerts.Count); Assert.AreEqual("Test title", contractsAlerts.Single().Title); Assert.IsNotNull(contractsAlerts.Single().ResolutionParameters); // Assert the detector's state Assert.AreEqual(2, this.stateRepository.Count); Assert.AreEqual("test state", this.stateRepository["test key"]); Assert.IsInstanceOfType(this.stateRepository[$"_autoResolve{contractsAlerts.Single().CorrelationHash}"], typeof(ResolutionState)); var resolutionState = (ResolutionState)this.stateRepository[$"_autoResolve{contractsAlerts.Single().CorrelationHash}"]; Assert.AreEqual(1, resolutionState.AlertPredicates.Count); Assert.AreEqual("Predicate value", resolutionState.AlertPredicates["Predicate"]); }
private async Task RunSmartDetectorWithResourceTypes(ResourceType requestResourceType, ResourceType smartDetectorResourceType, bool shouldFail) { this.TestInitialize(requestResourceType, smartDetectorResourceType); ISmartDetectorRunner runner = this.testContainer.Resolve <ISmartDetectorRunner>(); try { List <ContractsAlert> alertPresentations = await runner.RunAsync(this.request, true, default(CancellationToken)); if (shouldFail) { Assert.Fail("An exception should have been thrown - resource types are not compatible"); } Assert.AreEqual(1, alertPresentations.Count); } catch (IncompatibleResourceTypesException) { if (!shouldFail) { throw; } } }
public async Task WhenRunningSmartDetectorCheckResolutionAndStateIsNotFoundThenExceptionIsThrown() { // Run the Smart Detector and validate results ISmartDetectorRunner runner = this.testContainer.Resolve <ISmartDetectorRunner>(); await runner.CheckResolutionAsync(this.alertResolutionCheckRequest, true, default(CancellationToken)); }
/// <summary> /// Run the Smart Detector, by delegating the call to the registered <see cref="ISmartDetectorRunner"/> /// </summary> /// <param name="request">The Smart Detector request</param> /// <param name="cancellationToken">The cancellation token</param> /// <returns>A <see cref="Task{TResult}"/>, returning the alerts presentations generated by the Smart Detector</returns> private static async Task <List <ContractsAlert> > RunSmartDetectorAsync(SmartDetectorExecutionRequest request, CancellationToken cancellationToken) { ISmartDetectorRunner smartDetectorRunner = container.Resolve <ISmartDetectorRunner>(); return(await smartDetectorRunner.RunAsync(request, cancellationToken)); }