Example #1
0
        public void ValidateCacheHitOrMiss_SameUserAgent()
        {
            string resourceKey = "resource_key";
            string userAgent   = "iPhone";

            _jsonResponse = @"{ ""device"": { ""ismobile"": true } }";
            ConfigureMockedClient(r => true);

            var engine = new CloudRequestEngineBuilder(_loggerFactory, _httpClient)
                         .SetResourceKey(resourceKey)
                         .SetCacheSize(10)
                         .SetCacheHitOrMiss(true)
                         .Build();

            using (var pipeline = new PipelineBuilder(_loggerFactory).AddFlowElement(engine).Build())
            {
                var data1 = pipeline.CreateFlowData();
                data1.AddEvidence("query.User-Agent", userAgent);

                data1.Process();

                Assert.IsFalse(data1.GetFromElement(engine).CacheHit, "cache miss should occur.");

                var data2 = pipeline.CreateFlowData();
                data2.AddEvidence("query.User-Agent", userAgent);

                data2.Process();

                Assert.IsTrue(data2.GetFromElement(engine).CacheHit, "cache hit should occur.");
            }
        }
Example #2
0
        public void OriginHeader()
        {
            string resourceKey = "resource_key";
            string origin      = "51degrees.com";
            string userAgent   = "test";

            ConfigureMockedClient(r => true);
            var engine = new CloudRequestEngineBuilder(_loggerFactory, _httpClient)
                         .SetResourceKey(resourceKey)
                         .SetCloudRequestOrigin(origin)
                         .Build();

            using (var pipeline = new PipelineBuilder(_loggerFactory).AddFlowElement(engine).Build())
            {
                var data = pipeline.CreateFlowData();
                data.AddEvidence("query.User-Agent", userAgent);

                data.Process();
            }

            _handlerMock.Protected().Verify(
                "SendAsync",
                Times.Exactly(1),                                            // we expected a single external request
                ItExpr.Is <HttpRequestMessage>(req =>
                                               req.Method == HttpMethod.Post // we expected a POST request
                                                                             // The origin header must contain the expected value
                                               && ((req.Content.Headers.Contains(Constants.ORIGIN_HEADER_NAME) &&
                                                    req.Content.Headers.GetValues(Constants.ORIGIN_HEADER_NAME).Contains(origin)) ||
                                                   (req.Headers.Contains(Constants.ORIGIN_HEADER_NAME) &&
                                                    req.Headers.GetValues(Constants.ORIGIN_HEADER_NAME).Contains(origin)))
                                               ),
                ItExpr.IsAny <CancellationToken>()
                );
        }
Example #3
0
        public void JsonBuilder_LazyLoading()
        {
            var engine = new EmptyEngineBuilder(_loggerFactory)
                         .SetLazyLoadingTimeout(1000)
                         .SetProcessCost(TimeSpan.FromMilliseconds(500).Ticks)
                         .Build();
            var jsonBuilder = new JsonBuilderElementBuilder(_loggerFactory)
                              .Build();
            var sequenceElement = new SequenceElementBuilder(_loggerFactory)
                                  .Build();
            var pipeline = new PipelineBuilder(_loggerFactory)
                           .AddFlowElement(sequenceElement)
                           .AddFlowElement(engine)
                           .AddFlowElement(jsonBuilder)
                           .Build();

            var flowData = pipeline.CreateFlowData();

            Trace.WriteLine("Process starting");
            flowData.Process();
            Trace.WriteLine("Process complete");

            var jsonResult = flowData.Get <IJsonBuilderElementData>();

            Assert.IsNotNull(jsonResult);
            Assert.IsNotNull(jsonResult.Json);

            var jsonData = JsonConvert.DeserializeObject <JsonData>(jsonResult.Json);

            Assert.AreEqual(1, jsonData.EmptyAspect.Valueone);
            Assert.AreEqual(2, jsonData.EmptyAspect.Valuetwo);
            Trace.WriteLine("Data validated");
        }
Example #4
0
        public void RunExample()
        {
            //! [usage]
            // Construct a cloud request engine using the example endpoint for
            // the example engine to use.
            var cloudRequestEngine =
                new CloudRequestEngineBuilder(_loggerFactory, new HttpClient())
                .SetEndPoint("http://51degrees.com/starsign/api/")
                .SetResourceKey("cloudexample")
                .Build();
            // Construct the example engine.
            var starSignEngine =
                new SimpleCloudEngineBuilder(_loggerFactory, cloudRequestEngine)
                .Build();
            // Construct the pipeline with the example engine and the cloud
            // request engine it requires.
            var pipeline = new PipelineBuilder(_loggerFactory)
                           .AddFlowElement(cloudRequestEngine)
                           .AddFlowElement(starSignEngine)
                           .Build();

            var dob = "18/12/1992";
            // Create a new flow data.
            var flowData = pipeline.CreateFlowData();

            // Add the evidence and process the data.
            flowData
            .AddEvidence("date-of-birth", dob)
            .Process();
            // Now get the result of the processing.
            Console.WriteLine($"With a date of birth of {dob}, " +
                              $"your star sign is {flowData.Get<IStarSignData>().StarSign}.");
            //! [usage]
        }
Example #5
0
        static void Main(string[] args)
        {
            var ct = new CancellationToken();

            var cfg = new LazyLoadingConfiguration(10000, ct);

            var engine = new CloudRequestEngineBuilder(_loggerFactory, _httpClient)
                         .SetEndPoint("https://cloud.51degrees.com/api/v4/json")
                         // Obtain a resource key from https://configure.51degrees.com
                         .SetResourceKey("AQS5HKcyHJbECm6E10g")
                         .SetLazyLoading(cfg)
                         .Build();


            using (var pipeline = new PipelineBuilder(_loggerFactory).AddFlowElement(engine).Build())
            {
                var data = pipeline.CreateFlowData();
                data.AddEvidence("query.User-Agent", "iPhone");
                data.Process();
                var result = data.GetFromElement(engine).JsonResponse;
                Console.WriteLine(result);
            }

            Console.ReadKey();
        }
        public void PipelineIntegration_StopFlag()
        {
            // Configure the pipeline
            var stopElement = new StopElement();
            var testElement = new Mock <IFlowElement>();

            testElement.SetupGet(e => e.ElementDataKey).Returns("test");
            testElement.SetupGet(e => e.Properties).Returns(new List <IElementPropertyMetaData>());
            var pipeline = new PipelineBuilder(new LoggerFactory())
                           .AddFlowElement(stopElement)
                           .AddFlowElement(testElement.Object)
                           .Build();

            // Create and process flow data
            using (var flowData = pipeline.CreateFlowData())
            {
                flowData.Process();

                // Check that the stop flag is set
#pragma warning disable CS0618 // Type or member is obsolete
                // This usage will be replaced once the Cancellation Token
                // mechanism is available.
                Assert.IsTrue(flowData.Stop);
#pragma warning restore CS0618 // Type or member is obsolete
            }
            // Check that the second element was never processed
            testElement.Verify(e => e.Process(It.IsAny <IFlowData>()), Times.Never());
        }
Example #7
0
        public void RunExample()
        {
            //! [usage]
            // Construct the engine.
            var starSignElement = new SimpleFlowElementBuilder(_loggerFactory)
                                  .Build();
            // Construct the pipeline with the example engine.
            var pipeline = new PipelineBuilder(_loggerFactory)
                           .AddFlowElement(starSignElement)
                           .Build();

            var dob = new DateTime(1992, 12, 18);
            // Create a new flow data.
            var flowData = pipeline.CreateFlowData();

            // Add the evidence and process the data.
            flowData
            .AddEvidence("date-of-birth", dob)
            .Process();
            // Now get the result of the processing.
            Console.WriteLine($"With a date of birth of " +
                              $"{dob.ToString("dd/MM/yyy")}" +
                              $", your star sign is " +
                              $"{flowData.Get<IStarSignData>().StarSign}.");
            //! [usage]
        }
Example #8
0
        public void RunExample()
        {
            //! [usage]
            // Construct the engine using the data file. Let's disable auto
            // updates as we have not implemented it in this example engine.
            var starSignEngine = new SimpleOnPremiseEngineBuilder(_loggerFactory, null)
                                 .SetAutoUpdate(false)
                                 .SetDataFileSystemWatcher(false)
                                 .Build("starsigns.csv", false);
            // Construct the pipeline with the example engine.
            var pipeline = new PipelineBuilder(_loggerFactory)
                           .AddFlowElement(starSignEngine)
                           .Build();

            var dob = new DateTime(1992, 12, 18);
            // Create a new flow data.
            var flowData = pipeline.CreateFlowData();

            // Add the evidence and process the data.
            flowData
            .AddEvidence("date-of-birth", dob)
            .Process();
            // Now get the result of the processing.
            Console.WriteLine($"With a date of birth of {dob}, " +
                              $"your star sign is {flowData.Get<IStarSignData>().StarSign}.");
            //! [usage]
        }
Example #9
0
        public void EvidencePrecedence(bool warn, string evidence1, string evidence2)
        {
            var evidence1Parts = evidence1.Split("=");
            var evidence2Parts = evidence2.Split("=");

            string resourceKey = "resource_key";

            ConfigureMockedClient(r =>
                                  r.Content.ReadAsStringAsync().Result.Contains(evidence1.Split('.').Last())
                                  );

            var loggerFactory = new TestLoggerFactory();

            var engine = new CloudRequestEngineBuilder(loggerFactory, _httpClient)
                         .SetResourceKey(resourceKey)
                         .Build();

            using (var pipeline = new PipelineBuilder(loggerFactory).AddFlowElement(engine).Build())
            {
                var data = pipeline.CreateFlowData();

                data.AddEvidence(evidence1Parts[0], evidence1Parts[1]);
                data.AddEvidence(evidence2Parts[0], evidence2Parts[1]);

                data.Process();
            }

            // Get loggers.
            var loggers = loggerFactory.Loggers
                          .Where(l => l.GetType().IsAssignableFrom(typeof(TestLogger <FlowElements.CloudRequestEngine>)));
            var logger = loggers.FirstOrDefault();

            // If warn is expected then check for warnings from cloud request
            // engine.
            if (warn)
            {
                logger.AssertMaxWarnings(1);
                logger.AssertMaxErrors(0);
                Assert.AreEqual(1, logger.WarningsLogged.Count);
                var warning = logger.WarningsLogged.Single();
                Assert.IsTrue(warning.Contains($"'{evidence1}' evidence conflicts with '{evidence2}'"));
            }
            else
            {
                logger.AssertMaxWarnings(0);
                logger.AssertMaxErrors(0);
            }

            _handlerMock.Protected().Verify(
                "SendAsync",
                Times.Exactly(1), // we expected a single external request
                ItExpr.Is <HttpRequestMessage>(req =>
                                               req.Method == HttpMethod.Post && // we expected a POST request
                                               req.RequestUri == expectedUri // to this uri
                                               ),
                ItExpr.IsAny <CancellationToken>()
                );
        }
Example #10
0
        public void Process_NoCloudResponse()
        {
            // Setup properties.
            List <PropertyMetaData> properties = new List <PropertyMetaData>();

            properties.Add(new PropertyMetaData()
            {
                Name = "ismobile", Type = "Boolean"
            });
            ProductMetaData devicePropertyData = new ProductMetaData();

            devicePropertyData.Properties = properties;
            _propertiesReturnedByRequestEngine.Add("test", devicePropertyData);

            // Create mock TestInstance so we can see if the ProcessCloudEngine
            // method is called.
            var mockTestInstance = new Mock <TestInstance>()
            {
                CallBase = true
            };

            mockTestInstance.Protected().Setup(
                "ProcessCloudEngine",
                ItExpr.IsAny <IFlowData>(),
                ItExpr.IsAny <TestData>(),
                ItExpr.IsAny <string>()).Verifiable();

            // Create mock TestRequestEngine
            var mockRequestEngine = new Mock <TestRequestEngine>()
            {
                CallBase = true
            };

            mockRequestEngine.Object.PublicProperties = _propertiesReturnedByRequestEngine;

            // Construct the pipeline.
            var pipeline = new PipelineBuilder(new LoggerFactory())
                           .AddFlowElement(mockRequestEngine.Object)
                           .AddFlowElement(mockTestInstance.Object)
                           .Build();

            // Process the pipeline.
            using (var flowData = pipeline.CreateFlowData())
            {
                flowData
                .AddEvidence("query.user-agent", "iPhone")
                .Process();
            }

            // Verify the ProcessCloudEngine method was called
            mockTestInstance.Protected().Verify(
                "ProcessCloudEngine",
                Times.Never(),
                ItExpr.IsAny <IFlowData>(),
                ItExpr.IsAny <TestData>(),
                ItExpr.IsAny <string>());
        }
Example #11
0
        public void ValidateCacheHitOrMiss_DifferentUserAgent_SameLocation(bool hit, params string[] evidenceKeys)
        {
            string resourceKey = "resource_key";
            string userAgent1  = "iPhone";
            string userAgent2  = "Samsung";
            string latlon      = "51";

            _evidenceKeysResponse = $"[ '{string.Join("', '", evidenceKeys)}' ]";

            _jsonResponse = @"{ ""device"": { ""ismobile"": true } }";
            ConfigureMockedClient(r => true);

            var engine = new CloudRequestEngineBuilder(_loggerFactory, _httpClient)
                         .SetResourceKey(resourceKey)
                         .SetCacheSize(10)
                         .SetCacheHitOrMiss(true)
                         .Build();

            using (var pipeline = new PipelineBuilder(_loggerFactory).AddFlowElement(engine).Build())
            {
                var data1 = pipeline.CreateFlowData();
                data1.AddEvidence("query.User-Agent", userAgent1);
                data1.AddEvidence("query.51d_pos_latitude", latlon);
                data1.AddEvidence("query.51d_pos_longitude", latlon);
                data1.Process();

                Assert.IsFalse(data1.GetFromElement(engine).CacheHit, "cache miss should occur.");

                var data2 = pipeline.CreateFlowData();
                data2.AddEvidence("query.User-Agent", userAgent2);
                data2.AddEvidence("query.51d_pos_latitude", latlon);
                data2.AddEvidence("query.51d_pos_longitude", latlon);

                data2.Process();

                Assert.AreEqual(hit, data2.GetFromElement(engine).CacheHit, $"cache hit {(hit ? "should" : "shouldn't")} occur.");
            }
        }
Example #12
0
        public void AspectEngineLazyLoad_Itegrated()
        {
            // Arrange
            // Set the process time to half of the configured timeout
            var processCostMs = _timeoutMS / 2;

            _engine.SetProcessCost(TimeSpan.TicksPerMillisecond * processCostMs);
            var pipeline = new PipelineBuilder(_loggerFactory)
                           .AddFlowElement(_engine)
                           .Build();

            // Act
            var stopwatch = new Stopwatch();
            var flowData  = pipeline.CreateFlowData();

            Trace.WriteLine("Process starting");
            stopwatch.Start();
            flowData.Process();
            long processTimeMs = stopwatch.ElapsedMilliseconds;

            Trace.WriteLine($"Process complete in {processTimeMs} ms");
            Assert.IsTrue(processTimeMs < processCostMs,
                          $"Process time should have been less than " +
                          $"{processCostMs} ms but it took {processTimeMs} ms.");

            // Assert
            var data = flowData.Get <EmptyEngineData>();

            Assert.IsNotNull(data);
            Assert.AreEqual(1, data.ValueOne);
            long valueOneTimeMs = stopwatch.ElapsedMilliseconds;

            Trace.WriteLine($"Value one accessed after {valueOneTimeMs} ms");
            Assert.AreEqual(2, data.ValueTwo);
            long valueTwoTimeMs = stopwatch.ElapsedMilliseconds;

            Trace.WriteLine($"Value two accessed after {valueTwoTimeMs} ms");

            Assert.IsTrue(valueOneTimeMs < processCostMs,
                          $"Accessing value one should have taken less than " +
                          $"{processCostMs} ms from the time the Process method" +
                          $"was called but it took {valueOneTimeMs} ms.");
            // Note - this should really take at least 'processCostMs'
            // but the accuracy of the timer seems to cause issues
            // if we are being that exact.
            Assert.IsTrue(valueTwoTimeMs >= processCostMs / 2,
                          $"Accessing value two should have taken at least " +
                          $"{processCostMs / 2} ms from the time the Process method" +
                          $"was called but it only took {valueTwoTimeMs} ms.");
        }
Example #13
0
        public void ValidateCacheHitOrMiss_SameUserAgent_AdditionalHeaders()
        {
            string resourceKey   = "resource_key";
            string userAgent     = "iPhone";
            string xOperaMiniUA1 = "SonyEricsson/W810i";
            string xOperaMiniUA2 = "Nokia/3310";

            _evidenceKeysResponse = "[ 'query.User-Agent', 'header.X-OperaMini-Phone-UA' ]";

            _jsonResponse = @"{ ""device"": { ""ismobile"": true } }";
            ConfigureMockedClient(r => true);

            var engine = new CloudRequestEngineBuilder(_loggerFactory, _httpClient)
                         .SetResourceKey(resourceKey)
                         .SetCacheSize(10)
                         .SetCacheHitOrMiss(true)
                         .Build();

            using (var pipeline = new PipelineBuilder(_loggerFactory).AddFlowElement(engine).Build())
            {
                var data1 = pipeline.CreateFlowData();
                data1.AddEvidence("query.User-Agent", userAgent);
                data1.AddEvidence("header.X-OperaMini-Phone-UA", xOperaMiniUA1);

                data1.Process();

                Assert.IsFalse(data1.GetFromElement(engine).CacheHit, "cache miss should occur.");

                var data2 = pipeline.CreateFlowData();
                data2.AddEvidence("query.User-Agent", userAgent);
                data2.AddEvidence("header.X-OperaMini-Phone-UA", xOperaMiniUA2);

                data2.Process();

                Assert.IsFalse(data2.GetFromElement(engine).CacheHit, "cache miss should occur.");
            }
        }
        public void PipelineIntegration_SingleElement()
        {
            var fiveElement = new MultiplyByFiveElement();
            var pipeline    = new PipelineBuilder(new LoggerFactory())
                              .AddFlowElement(fiveElement)
                              .Build();

            var flowData = pipeline.CreateFlowData();

            flowData.AddEvidence(fiveElement.EvidenceKeys[0], 2);

            flowData.Process();

            Assert.AreEqual(10, flowData.GetFromElement(fiveElement).Result);
        }
Example #15
0
        public void ValidateErrorHandling_MultipleErrors()
        {
            string resourceKey = "resource_key";
            string userAgent   = "iPhone";

            _jsonResponse = @"{ ""errors"": [""This resource key is not authorized for use with this domain: . Please visit https://configure.51degrees.com to update your resource key."",""Some other error""] }";

            ConfigureMockedClient(r =>
                                  r.Content.ReadAsStringAsync().Result.Contains($"resource={resourceKey}") && // content contains resource key
                                  r.Content.ReadAsStringAsync().Result.Contains($"User-Agent={userAgent}") // content contains licenseKey
                                  );

            var engine = new CloudRequestEngineBuilder(_loggerFactory, _httpClient)
                         .SetResourceKey(resourceKey)
                         .Build();

            Exception exception = null;

            try
            {
                using (var pipeline = new PipelineBuilder(_loggerFactory).AddFlowElement(engine).Build())
                {
                    var data = pipeline.CreateFlowData();
                    data.AddEvidence("query.User-Agent", userAgent);

                    data.Process();
                }
            }
            catch (Exception ex)
            {
                exception = ex;
            }

            Assert.IsNotNull(exception, "Expected exception to occur");
            Assert.IsInstanceOfType(exception, typeof(AggregateException));
            var aggEx = (exception as AggregateException).Flatten();

            Assert.AreEqual(aggEx.InnerExceptions.Count, 2);
            Assert.IsInstanceOfType(aggEx.InnerExceptions[0], typeof(PipelineException));
            Assert.IsInstanceOfType(aggEx.InnerExceptions[1], typeof(PipelineException));
            Assert.IsTrue(aggEx.InnerExceptions.Any(e => e.Message.Contains(
                                                        "This resource key is not authorized for use with this domain")),
                          "Exception message did not contain the expected text.");
            Assert.IsTrue(aggEx.InnerExceptions.Any(e => e.Message.Contains(
                                                        "Some other error")),
                          "Exception message did not contain the expected text.");
        }
Example #16
0
        public void Process_LicenseKey()
        {
            string resourceKey = "resource_key";
            string userAgent   = "iPhone";
            string licenseKey  = "ABCDEFG";

            ConfigureMockedClient(r =>
                                  r.Content.ReadAsStringAsync().Result.Contains($"resource={resourceKey}") && // content contains resource key
                                  r.Content.ReadAsStringAsync().Result.Contains($"license={licenseKey}") && // content contains licenseKey
                                  r.Content.ReadAsStringAsync().Result.Contains($"User-Agent={userAgent}") // content contains user agent
                                  );

#pragma warning disable CS0618 // Type or member is obsolete
            // SetLicensekey is obsolete but we still want to test that
            // it works as intended.
            var engine = new CloudRequestEngineBuilder(_loggerFactory, _httpClient)
                         .SetResourceKey(resourceKey)
                         .SetLicenseKey(licenseKey)
#pragma warning restore CS0618 // Type or member is obsolete
                         .Build();

            using (var pipeline = new PipelineBuilder(_loggerFactory).AddFlowElement(engine).Build())
            {
                var data = pipeline.CreateFlowData();
                data.AddEvidence("query.User-Agent", userAgent);

                data.Process();

                var result = data.GetFromElement(engine).JsonResponse;
                Assert.AreEqual("{'device':{'value':'1'}}", result);

                dynamic obj = JValue.Parse(result);
                Assert.AreEqual(1, (int)obj.device.value);
            }

            _handlerMock.Protected().Verify(
                "SendAsync",
                Times.Exactly(1), // we expected a single external request
                ItExpr.Is <HttpRequestMessage>(req =>
                                               req.Method == HttpMethod.Post && // we expected a POST request
                                               req.RequestUri == expectedUri // to this uri
                                               ),
                ItExpr.IsAny <CancellationToken>()
                );
        }
        public void PipelineBuilder_BuildFromConfiguration_ServiceCollection()
        {
            var element = new ElementOptions()
            {
                BuilderName = "MultiplyByElementBuilder"
            };

            element.BuildParameters.Add("multiple", "3");

            // Create the configuration object.
            PipelineOptions opts = new PipelineOptions();

            opts.Elements = new List <ElementOptions>
            {
                element
            };

            Mock <IServiceProvider> services = new Mock <IServiceProvider>();

            services.Setup(s => s.GetService(typeof(MultiplyByElementBuilder)))
            .Returns(new MultiplyByElementBuilder());

            // Pass the configuration to the builder to create the pipeline.
            var pipeline = new PipelineBuilder(_loggerFactory, services.Object)
                           .BuildFromConfiguration(opts);

            // Get the element
            var multiplyByElement = pipeline.GetElement <MultiplyByElement>();

            // Create, populate and process flow data.
            using (var flowData = pipeline.CreateFlowData())
            {
                flowData
                .AddEvidence(multiplyByElement.EvidenceKeys[0], 25)
                .Process();

                // Get the results and verify them.
                var multiplyByData = flowData.GetFromElement(multiplyByElement);

                Assert.AreEqual(75, multiplyByData.Result);
            }
        }
Example #18
0
        public void AspectEngineLazyLoad_Itegrated_AsDictionary()
        {
            // Arrange
            var processCostMs = _timeoutMS / 2;

            _engine.SetProcessCost(TimeSpan.TicksPerMillisecond * processCostMs);
            var pipeline = new PipelineBuilder(_loggerFactory)
                           .AddFlowElement(_engine)
                           .Build();

            // Act
            var stopwatch = new Stopwatch();
            var flowData  = pipeline.CreateFlowData();

            Trace.WriteLine("Process starting");
            stopwatch.Start();
            flowData.Process();
            long processTimeMs = stopwatch.ElapsedMilliseconds;

            Trace.WriteLine($"Process complete in {processTimeMs} ms");

            // Assert
            var data = flowData.Get <EmptyEngineData>();

            Assert.IsNotNull(data);
            var  dictionary = data.AsDictionary();
            long dictTimeMs = stopwatch.ElapsedMilliseconds;

            Trace.WriteLine($"Dictionary retrieved after {dictTimeMs} ms");
            Assert.AreEqual(1, dictionary[EmptyEngineData.VALUE_ONE_KEY]);
            Assert.AreEqual(2, dictionary[EmptyEngineData.VALUE_TWO_KEY]);

            // Note - this should really take at least 'processCostMs'
            // but the accuracy of the timer seems to cause issues
            // if we are being that exact.
            Assert.IsTrue(dictTimeMs > processCostMs / 2,
                          $"Accessing the dictionary should have taken at least " +
                          $"{processCostMs / 2} ms from the time the Process method" +
                          $"was called but it only took {dictTimeMs} ms.");
        }
Example #19
0
        public void ValidateErrorHandling_NoData()
        {
            string resourceKey = "resource_key";
            string userAgent   = "iPhone";

            _jsonResponse = @"{ }";

            ConfigureMockedClient(r =>
                                  r.Content.ReadAsStringAsync().Result.Contains($"resource={resourceKey}") && // content contains resource key
                                  r.Content.ReadAsStringAsync().Result.Contains($"User-Agent={userAgent}") // content contains licenseKey
                                  );

            var engine = new CloudRequestEngineBuilder(_loggerFactory, _httpClient)
                         .SetResourceKey(resourceKey)
                         .Build();

            using (var pipeline = new PipelineBuilder(_loggerFactory).AddFlowElement(engine).Build())
            {
                var data = pipeline.CreateFlowData();
                data.AddEvidence("query.User-Agent", userAgent);

                data.Process();
            }
        }
Example #20
0
        public void EvidencePrecedenceMultipleConflicts(params string[] evidence)
        {
            string resourceKey = "resource_key";

            // Get a list of evidence that should not be in the result.
            var excludedEvidence = evidence
                                   .Select(e => e.Split('.').Last())
                                   .Distinct()
                                   .Where(e => e != evidence[0].Split('.').Last());

            ConfigureMockedClient(r =>
            {
                var valid = true || excludedEvidence.Count() > 0;
                // Check that excluded evidence is not in the result.
                foreach (var item in excludedEvidence)
                {
                    valid = r.Content.ReadAsStringAsync().Result.Contains(item) == false;
                    if (valid == false)
                    {
                        break;
                    }
                }

                // Check that the expected evidence is in the result.
                return(r.Content.ReadAsStringAsync().Result.Contains(evidence[0].Split('.').Last()) && valid);
            });

            var loggerFactory = new TestLoggerFactory();

            var engine = new CloudRequestEngineBuilder(loggerFactory, _httpClient)
                         .SetResourceKey(resourceKey)
                         .Build();

            using (var pipeline = new PipelineBuilder(loggerFactory).AddFlowElement(engine).Build())
            {
                var data = pipeline.CreateFlowData();

                foreach (var item in evidence)
                {
                    var evidenceParts = item.Split("=");
                    data.AddEvidence(evidenceParts[0], evidenceParts[1]);
                }

                data.Process();
            }

            // Get loggers.
            var loggers = loggerFactory.Loggers
                          .Where(l => l.GetType().IsAssignableFrom(typeof(TestLogger <FlowElements.CloudRequestEngine>)));
            var logger = loggers.FirstOrDefault();

            // Check that the expected number of warnings has been logged.
            logger.AssertMaxWarnings(evidence.Length - 1);
            logger.AssertMaxErrors(0);
            Assert.AreEqual(evidence.Length - 1, logger.WarningsLogged.Count);
            // Check that only conflict warnings have been logged.
            foreach (var warning in logger.WarningsLogged)
            {
                Assert.IsTrue(warning.Contains("evidence conflicts"));
            }

            _handlerMock.Protected().Verify(
                "SendAsync",
                Times.Exactly(1), // we expected a single external request
                ItExpr.Is <HttpRequestMessage>(req =>
                                               req.Method == HttpMethod.Post && // we expected a POST request
                                               req.RequestUri == expectedUri // to this uri
                                               ),
                ItExpr.IsAny <CancellationToken>()
                );
        }
Example #21
0
        public void CloudEngines_WrongOrder()
        {
            // Setup properties.
            List <PropertyMetaData> properties = new List <PropertyMetaData>();

            properties.Add(new PropertyMetaData()
            {
                Name = "ismobile", Type = "Boolean"
            });
            ProductMetaData devicePropertyData = new ProductMetaData();

            devicePropertyData.Properties = properties;
            _propertiesReturnedByRequestEngine.Add("test", devicePropertyData);

            // Create mock TestInstance so we can see if the ProcessCloudEngine
            // method is called.
            var mockTestInstance = new Mock <TestInstance>()
            {
                CallBase = true
            };

            mockTestInstance.Protected().Setup(
                "ProcessCloudEngine",
                ItExpr.IsAny <IFlowData>(),
                ItExpr.IsAny <TestData>(),
                ItExpr.IsAny <string>()).Verifiable();

            // Create mock TestRequestEngine so we can mock the ProcessEngine
            // method and get it to set it's aspect data.
            var mockRequestEngine = new Mock <TestRequestEngine>()
            {
                CallBase = true
            };

            mockRequestEngine.Object.PublicProperties = _propertiesReturnedByRequestEngine;
            mockRequestEngine.Protected()
            .Setup(
                "ProcessEngine",
                ItExpr.IsAny <IFlowData>(),
                ItExpr.IsAny <CloudRequestData>())
            .Callback((IFlowData data, CloudRequestData aspectData) => {
                aspectData.JsonResponse   = "{ \"response\": true }";
                aspectData.ProcessStarted = true;
            });

            // Construct the pipeline.
            var pipeline = new PipelineBuilder(new LoggerFactory())
                           .AddFlowElement(mockTestInstance.Object)
                           .AddFlowElement(mockRequestEngine.Object)
                           .Build();

            // Process the pipeline.
            try
            {
                using (var flowData = pipeline.CreateFlowData())
                {
                    flowData
                    .AddEvidence("query.user-agent", "iPhone")
                    .Process();
                }
            }
            catch (AggregateException ex)
            {
                var expectedExceptions = ex.InnerExceptions
                                         .Where(e => e.GetType() == typeof(PipelineConfigurationException));

                Assert.IsTrue(
                    expectedExceptions.Count() > 0,
                    "Aggregate exception did not contain expected PipelineConfigurationException.");
                Assert.AreEqual(
                    "The 'TestInstanceProxy' requires a 'CloudRequestEngine' " +
                    "before it in the Pipeline. This engine will be unable to " +
                    "produce results until this is corrected.",
                    expectedExceptions.FirstOrDefault()?.Message,
                    "PipelineConfigurationException message was incorrect.");
            }
        }