Example #1
0
        public void AspectEngineLazyLoad_ProcessCancelled()
        {
            // Arrange
            // Set the process time to the configured timeout
            _engine.SetProcessCost(TimeSpan.TicksPerMillisecond * _timeoutMS);

            // Act
            var evidence = new Dictionary <string, object>()
            {
                { "user-agent", "1234" }
            };
            // Use the mock flow data to populate this variable with the
            // engine data from the call to process.
            var             mockData   = MockFlowData.CreateFromEvidence(evidence, false);
            EmptyEngineData engineData = null;

            mockData.Setup(d => d.GetOrAdd(It.IsAny <ITypedKey <EmptyEngineData> >(),
                                           It.IsAny <Func <IPipeline, EmptyEngineData> >()))
            .Callback((ITypedKey <EmptyEngineData> k, Func <IPipeline, EmptyEngineData> f) =>
            {
                engineData = f(mockData.Object.Pipeline);
            })
            .Returns((ITypedKey <EmptyEngineData> k, Func <IPipeline, EmptyEngineData> f) =>
            {
                return(engineData);
            });
            var data = mockData.Object;

            // Process the data
            _engine.Process(data);

            // Ideally, start a new task that will wait a short time and
            // then trigger the cancellation token.
            // If we've only got one core to work with then this approach
            // can cause the test to fail as the cancellation task may
            // not get run in time.
            // If we only have one core then just trigger cancellation
            // up-front.
            if (Environment.ProcessorCount > 1)
            {
                Task.Run(() =>
                {
                    Task.Delay(_timeoutMS / 10);
                    _cancellationTokenSource.Cancel();
                });
            }
            else
            {
                _cancellationTokenSource.Cancel();
            }

            // Attempt to get the value.
            var result = engineData.ValueTwo;

            // These asserts are not really needed but can help work out
            // what is happening if the test fails to throw the expected
            // exception.
            Assert.IsTrue(_cancellationTokenSource.IsCancellationRequested);
            Assert.IsNull(result);
        }
        public void FlowElementCached_Process_CheckCachePut()
        {
            // Arrange
            var evidence = new Dictionary <string, object>()
            {
                { "user-agent", "1234" }
            };
            Mock <IFlowData> data       = MockFlowData.CreateFromEvidence(evidence, false);
            EmptyEngineData  aspectData = new EmptyEngineData(
                _loggerFactory.CreateLogger <EmptyEngineData>(),
                data.Object.Pipeline,
                _engine,
                MissingPropertyService.Instance);

            data.Setup(d => d.GetOrAdd(
                           It.IsAny <TypedKey <EmptyEngineData> >(),
                           It.IsAny <Func <IPipeline, EmptyEngineData> >()))
            .Returns(aspectData);

            _cache.Setup(c => c[It.IsAny <IFlowData>()])
            .Returns <IDictionary <string, object> >(null);

            // Act
            _engine.Process(data.Object);

            // Assert
            // Verify that the cache was checked to see if there was an
            // existing result for this key.
            _cache.Verify(c => c[It.Is <IFlowData>(d => d == data.Object)], Times.Once);
            // Verify that the result was added to the cache.
            _cache.Verify(c => c.Put(It.Is <IFlowData>(d => d == data.Object),
                                     It.IsAny <EmptyEngineData>()), Times.Once);
            // Verify the CacheHit flag is false.
            Assert.IsFalse(aspectData.CacheHit);
        }
        public void FlowElementCached_Process_CheckCacheGet()
        {
            // Arrange

            var evidence = new Dictionary <string, object>()
            {
                { "user-agent", "1234" }
            };
            var             mockData   = MockFlowData.CreateFromEvidence(evidence, false);
            IFlowData       data       = mockData.Object;
            EmptyEngineData cachedData = new EmptyEngineData(
                _loggerFactory.CreateLogger <EmptyEngineData>(),
                data.Pipeline,
                _engine,
                new Mock <IMissingPropertyService>().Object);

            cachedData.ValueOne = 2;
            _cache.Setup(c => c[It.IsAny <IFlowData>()])
            .Returns(cachedData);

            // Act
            _engine.Process(data);

            // Assert
            // Verify that the cached result was added to the flow data.
            mockData.Verify(d => d.GetOrAdd(
                                It.IsAny <ITypedKey <EmptyEngineData> >(),
                                It.Is <Func <IPipeline, EmptyEngineData> >(f => f(mockData.Object.Pipeline) == cachedData)), Times.Once());
            // Verify that the cache was checked once.
            _cache.Verify(c => c[It.Is <IFlowData>(d => d == data)], Times.Once);
            // Verify that the Put method of the cache was not called.
            _cache.Verify(c => c.Put(It.IsAny <IFlowData>(), It.IsAny <IElementData>()), Times.Never);
            // Verify the CacheHit flag is true.
            Assert.IsTrue(cachedData.CacheHit);
        }
Example #4
0
        public void AspectEngineLazyLoad_ProcessMultipleErrored()
        {
            // Arrange
            // Set the engine to throw an exception while processing
            var exceptionMessage = "an exception message";
            var engine2          = new EmptyEngineBuilder(_loggerFactory)
                                   .SetLazyLoading(new LazyLoadingConfiguration(_timeoutMS,
                                                                                _cancellationTokenSource.Token))
                                   .Build();

            _engine.SetException(new Exception(exceptionMessage));
            engine2.SetException(new Exception(exceptionMessage));
            // Act
            var evidence = new Dictionary <string, object>()
            {
                { "user-agent", "1234" }
            };
            // Use the mock flow data to populate this variable with the
            // engine data from the call to process.
            var             mockData   = MockFlowData.CreateFromEvidence(evidence, false);
            EmptyEngineData engineData = null;

            mockData.Setup(d => d.GetOrAdd(It.IsAny <ITypedKey <EmptyEngineData> >(),
                                           It.IsAny <Func <IPipeline, EmptyEngineData> >()))
            .Callback((ITypedKey <EmptyEngineData> k, Func <IPipeline, EmptyEngineData> f) =>
            {
                if (engineData == null)
                {
                    engineData = f(mockData.Object.Pipeline);
                }
            })
            .Returns((ITypedKey <EmptyEngineData> k, Func <IPipeline, EmptyEngineData> f) =>
            {
                return(engineData);
            });
            var data = mockData.Object;

            // Process the data twice
            _engine.Process(data);
            engine2.Process(data);

            // Attempt to get the value.
            try
            {
                var result = engineData.ValueOne;
            }
            catch (Exception e)
            {
                Assert.IsTrue(e is AggregateException);
                Assert.IsNotNull(((AggregateException)e).InnerExceptions);
                Assert.AreEqual(2, ((AggregateException)e).InnerExceptions.Count);
                Assert.AreEqual(
                    $"One or more errors occurred. ({exceptionMessage})",
                    ((AggregateException)e).InnerExceptions[0].Message);
                Assert.AreEqual(
                    $"One or more errors occurred. ({exceptionMessage})",
                    ((AggregateException)e).InnerExceptions[1].Message);
            }
        }
Example #5
0
        public void AspectEngineLazyLoad_ProcessErrored()
        {
            // Arrange
            // Set the engine to throw an exception while processing
            var exceptionMessage = "an exception message";

            _engine.SetException(new Exception(exceptionMessage));
            // Act
            var evidence = new Dictionary <string, object>()
            {
                { "user-agent", "1234" }
            };
            // Use the mock flow data to populate this variable with the
            // engine data from the call to process.
            var             mockData   = MockFlowData.CreateFromEvidence(evidence, false);
            EmptyEngineData engineData = null;

            mockData.Setup(d => d.GetOrAdd(It.IsAny <ITypedKey <EmptyEngineData> >(),
                                           It.IsAny <Func <IPipeline, EmptyEngineData> >()))
            .Callback((ITypedKey <EmptyEngineData> k, Func <IPipeline, EmptyEngineData> f) =>
            {
                engineData = f(mockData.Object.Pipeline);
            })
            .Returns((ITypedKey <EmptyEngineData> k, Func <IPipeline, EmptyEngineData> f) =>
            {
                return(engineData);
            });
            var data = mockData.Object;

            // Process the data
            _engine.Process(data);


            // Attempt to get the value.
            try
            {
                var result = engineData.ValueOne;
            }
            catch (Exception e)
            {
                Assert.IsTrue(e is Exception);
                Assert.IsNotNull(e.InnerException);
                Assert.AreEqual(
                    $"One or more errors occurred. ({exceptionMessage})",
                    e.InnerException.Message);
            }
        }
Example #6
0
        public void AspectEngineLazyLoad_Process()
        {
            // Arrange
            // Set the process time to half of the configured timeout
            _engine.SetProcessCost(TimeSpan.TicksPerMillisecond * (_timeoutMS / 2));

            // Act
            var evidence = new Dictionary <string, object>()
            {
                { "user-agent", "1234" }
            };
            var mockData = MockFlowData.CreateFromEvidence(evidence, false);
            // Use the mock flow data to populate this variable with the
            // engine data from the call to process.
            EmptyEngineData engineData = null;

            mockData.Setup(d => d.GetOrAdd(It.IsAny <ITypedKey <EmptyEngineData> >(),
                                           It.IsAny <Func <IPipeline, EmptyEngineData> >()))
            .Callback((ITypedKey <EmptyEngineData> k, Func <IPipeline, EmptyEngineData> f) =>
            {
                engineData = f(mockData.Object.Pipeline);
            })
            .Returns((ITypedKey <EmptyEngineData> k, Func <IPipeline, EmptyEngineData> f) =>
            {
                return(engineData);
            });
            var data = mockData.Object;

            // Process the data.
            _engine.Process(data);
            // Check that the task is not complete when process returns.
            bool processReturnedBeforeTaskComplete =
                engineData.ProcessTask.IsCompleted == false;

            // Assert
            Assert.AreEqual(2, engineData.ValueTwo);
            // Check that the task is now complete (because the code to get
            // the property value will wait until it is complete)
            bool valueReturnedAfterTaskComplete =
                engineData.ProcessTask.IsCompleted == true;

            Assert.IsTrue(processReturnedBeforeTaskComplete);
            Assert.IsTrue(valueReturnedAfterTaskComplete);
        }
        public void MultiEngineData_SimpleTest()
        {
            BuildEngine(false);

            IFlowData       data       = _pipeline.CreateFlowData();
            EmptyEngineData engineData = data.GetOrAdd(
                _engine.ElementDataKeyTyped,
                (f) => new EmptyEngineData(
                    _loggerFactory.CreateLogger <EmptyEngineData>(),
                    f,
                    _engine,
                    null));

            engineData.ValueOne   = 0;
            engineData.ValueThree = 50;
            data.Process();

            var result = data.Get <EmptyEngineData>();

            Assert.AreEqual(1, result.ValueOne);
            Assert.AreEqual(50, result.ValueThree);
        }
Example #8
0
        public void AspectEngineLazyLoad_PropertyTimeout()
        {
            // Arrange
            // Set the process time to double the configured timeout
            _engine.SetProcessCost(TimeSpan.TicksPerMillisecond * (_timeoutMS * 2));

            // Act
            var evidence = new Dictionary <string, object>()
            {
                { "user-agent", "1234" }
            };
            // Use the mock flow data to populate this variable with the
            // engine data from the call to process.
            var             mockData   = MockFlowData.CreateFromEvidence(evidence, false);
            EmptyEngineData engineData = null;

            mockData.Setup(d => d.GetOrAdd(It.IsAny <ITypedKey <EmptyEngineData> >(),
                                           It.IsAny <Func <IPipeline, EmptyEngineData> >()))
            .Callback((ITypedKey <EmptyEngineData> k, Func <IPipeline, EmptyEngineData> f) =>
            {
                engineData = f(mockData.Object.Pipeline);
            })
            .Returns((ITypedKey <EmptyEngineData> k, Func <IPipeline, EmptyEngineData> f) =>
            {
                return(engineData);
            });
            var data = mockData.Object;

            // Process the data
            _engine.Process(data);
            // Attempt to get the value. This should cause the timeout
            // to be triggered.
            var result = engineData.ValueTwo;

            // No asserts needed. Just the ExpectedException attribute
            // on the method.
        }