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);
        }
Example #9
0
        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>()));
        }
Example #14
0
        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"]);
        }
Example #19
0
        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));
 }
Example #23
0
        /// <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));
        }