Example #1
0
        public void DoesNotCrash()
        {
            var impressionHasher = new ImpressionHasher();

            var impression = new KeyImpression
            {
                feature      = null,
                keyName      = "someKeyName",
                treatment    = "someTreatment",
                changeNumber = 3245463,
                label        = "someLabel"
            };

            Assert.IsNotNull(impressionHasher.Process(impression));

            impression.keyName = null;
            Assert.IsNotNull(impressionHasher.Process(impression));

            impression.changeNumber = null;
            Assert.IsNotNull(impressionHasher.Process(impression));

            impression.label = null;
            Assert.IsNotNull(impressionHasher.Process(impression));

            impression.treatment = null;
            Assert.IsNotNull(impressionHasher.Process(impression));
        }
Example #2
0
        public void LogSuccessfullyUsingBucketingKey()
        {
            //Act
            Key key = new Key(bucketingKey: "a", matchingKey: "testkey");

            var impressions = new List <KeyImpression>
            {
                new KeyImpression {
                    keyName = key.matchingKey, feature = "test", treatment = "on", time = 7000, changeNumber = 1, label = "test-label", bucketingKey = key.bucketingKey
                }
            };

            _impressionsLog.Log(impressions);

            //Assert
            KeyImpression element = null;

            while (element == null)
            {
                element = _queue.Dequeue();
            }
            Assert.IsNotNull(element);
            Assert.AreEqual("testkey", element.keyName);
            Assert.AreEqual("a", element.bucketingKey);
            Assert.AreEqual("test", element.feature);
            Assert.AreEqual("on", element.treatment);
            Assert.AreEqual(7000, element.time);
        }
Example #3
0
        public void AddImpression(KeyImpression impression)
        {
            var key            = redisKeyPrefix + impressionKeyPrefix + impression.feature;
            var impressionJson = JsonConvert.SerializeObject(impression);

            redisAdapter.SAdd(key, impressionJson);
        }
Example #4
0
        public void AddImpressionWithFullQueue()
        {
            //Arrange
            var queue      = new BlockingQueue <KeyImpression>(1);
            var cache      = new InMemorySimpleCache <KeyImpression>(queue);
            var impression = new KeyImpression {
                feature = "test", changeNumber = 100, keyName = "date", label = "testdate", time = 10000000
            };
            var impression2 = new KeyImpression {
                feature = "test2", changeNumber = 100, keyName = "date", label = "testdate", time = 10000000
            };

            //Act
            cache.AddItems(new List <KeyImpression> {
                impression
            });
            cache.AddItems(new List <KeyImpression> {
                impression2
            });

            var element  = queue.Dequeue();
            var element2 = queue.Dequeue();

            //Assert
            Assert.IsNotNull(element);
            Assert.IsNull(element2);
        }
Example #5
0
        public void LogSuccessfully()
        {
            //Arrange
            var queue            = new BlockingQueue <KeyImpression>(10);
            var impressionsCache = new InMemoryImpressionsCache(queue);
            var treatmentLog     = new SelfUpdatingTreatmentLog(null, 1, impressionsCache, 10);

            //Act
            var impression = new KeyImpression()
            {
                keyName = "GetTreatment", feature = "test", treatment = "on", time = 7000, changeNumber = 1, label = "test"
            };

            treatmentLog.Log(impression);

            //Assert
            KeyImpression element = null;

            while (element == null)
            {
                element = queue.Dequeue();
            }
            Assert.IsNotNull(element);
            Assert.AreEqual("GetTreatment", element.keyName);
            Assert.AreEqual("test", element.feature);
            Assert.AreEqual("on", element.treatment);
            Assert.AreEqual(7000, element.time);
        }
Example #6
0
        public void FetchAllAndClearSuccessfully()
        {
            //Arrange
            var queue = new BlockingQueue <KeyImpression>(2);
            var cache = new InMemorySimpleCache <KeyImpression>(queue);

            var impression = new KeyImpression {
                feature = "test", changeNumber = 100, keyName = "date", label = "testdate", time = 10000000
            };
            var impression2 = new KeyImpression {
                feature = "test2", changeNumber = 100, keyName = "date", label = "testdate", time = 10000000
            };

            cache.AddItems(new List <KeyImpression> {
                impression
            });
            cache.AddItems(new List <KeyImpression> {
                impression2
            });

            //Act
            var result  = cache.FetchAllAndClear();
            var element = queue.Dequeue();

            //Assert
            Assert.IsNotNull(result);
            Assert.AreEqual(2, result.Count);
            Assert.IsNull(element);
        }
        public long?TestAndSet(KeyImpression impression)
        {
            long?defaultReturn = null;

            if (impression == null)
            {
                return(defaultReturn);
            }

            ulong hash = _impressionHasher.Process(impression);

            try
            {
                long?previous = _cache.Get(hash);
                _cache.AddOrUpdate(hash, impression.time);

                return(Math.Min(previous.Value, impression.time));
            }
            catch (Exception)
            {
                _cache.AddOrUpdate(hash, impression.time);

                return(defaultReturn);
            }
        }
Example #8
0
        public void LogSuccessfullyUsingBucketingKey()
        {
            //Arrange
            var queue            = new BlockingQueue <KeyImpression>(10);
            var impressionsCache = new InMemoryImpressionsCache(queue);
            var treatmentLog     = new SelfUpdatingTreatmentLog(null, 1, impressionsCache, 10);

            //Act
            Key key        = new Key(bucketingKey: "a", matchingKey: "testkey");
            var impression = new KeyImpression()
            {
                keyName = key.matchingKey, feature = "test", treatment = "on", time = 7000, changeNumber = 1, label = "test-label", bucketingKey = key.bucketingKey
            };

            treatmentLog.Log(impression);

            //Assert
            KeyImpression element = null;

            while (element == null)
            {
                element = queue.Dequeue();
            }
            Assert.IsNotNull(element);
            Assert.AreEqual("testkey", element.keyName);
            Assert.AreEqual("a", element.bucketingKey);
            Assert.AreEqual("test", element.feature);
            Assert.AreEqual("on", element.treatment);
            Assert.AreEqual(7000, element.time);
        }
Example #9
0
 public void AddImpression(KeyImpression impression)
 {
     if (queue != null)
     {
         queue.Enqueue(impression);
     }
 }
Example #10
0
        public void LogSuccessfully()
        {
            //Act
            var impressions = new List <KeyImpression>
            {
                new KeyImpression {
                    keyName = "GetTreatment", feature = "test", treatment = "on", time = 7000, changeNumber = 1, label = "test"
                }
            };

            _impressionsLog.Log(impressions);

            //Assert
            KeyImpression element = null;

            while (element == null)
            {
                element = _queue.Dequeue();
            }
            Assert.IsNotNull(element);
            Assert.AreEqual("GetTreatment", element.keyName);
            Assert.AreEqual("test", element.feature);
            Assert.AreEqual("on", element.treatment);
            Assert.AreEqual(7000, element.time);
        }
Example #11
0
        public void HasReachedMaxSizeWithNullQueue()
        {
            //Arrange
            var queue = new BlockingQueue <KeyImpression>(3);
            var cache = new InMemorySimpleCache <KeyImpression>(queue);

            var impression = new KeyImpression {
                feature = "test", changeNumber = 100, keyName = "date", label = "testdate", time = 10000000
            };
            var impression2 = new KeyImpression {
                feature = "test2", changeNumber = 100, keyName = "date", label = "testdate", time = 10000000
            };

            cache.AddItems(new List <KeyImpression> {
                impression
            });
            cache.AddItems(new List <KeyImpression> {
                impression2
            });

            //Act
            var result = cache.HasReachedMaxSize();

            //Assert
            Assert.IsFalse(result);
        }
Example #12
0
 protected void AssertImpression(KeyImpression impression, long changeNumber, string feature, string keyName, string label, string treatment)
 {
     Assert.AreEqual(changeNumber, impression.changeNumber);
     Assert.AreEqual(feature, impression.feature);
     Assert.AreEqual(keyName, impression.keyName);
     Assert.AreEqual(label, impression.label);
     Assert.AreEqual(treatment, impression.treatment);
 }
Example #13
0
        public void Log(KeyImpression impression)
        {
            if (queue.HasReachedMaxSize())
            {
                queue.Dequeue();
            }

            queue.Enqueue(impression);
        }
Example #14
0
        public void TestAndSet()
        {
            var impressionsObserver = new ImpressionsObserver(new ImpressionHasher());

            var impression = new KeyImpression
            {
                keyName      = "matching_key",
                bucketingKey = "bucketing_key",
                feature      = "split_name",
                treatment    = "treatment",
                label        = "default label",
                changeNumber = 1533177602748,
                time         = 1478113516022
            };

            var impression2 = new KeyImpression
            {
                keyName      = "matching_key_2",
                bucketingKey = "bucketing_key_2",
                feature      = "split_name_2",
                treatment    = "treatment_2",
                label        = "default label_2",
                changeNumber = 1533177602748,
                time         = 1478113516022
            };

            var result = impressionsObserver.TestAndSet(impression);

            Assert.IsNull(result);

            // Should return previous time
            impression.time = 1478113516500;
            result          = impressionsObserver.TestAndSet(impression);
            Assert.AreEqual(1478113516022, result);

            // Should return the new impression.time
            result = impressionsObserver.TestAndSet(impression);
            Assert.AreEqual(1478113516500, result);

            // When impression.time < previous should return the min.
            impression.time = 1478113516001;
            result          = impressionsObserver.TestAndSet(impression);
            Assert.AreEqual(1478113516001, result);

            // Should return null because is another impression
            result = impressionsObserver.TestAndSet(impression2);
            Assert.IsNull(result);

            // Should return previous time
            impression2.time = 1478113516500;
            result           = impressionsObserver.TestAndSet(impression2);
            Assert.AreEqual(1478113516022, result);

            // Should return null because the impression is null
            result = impressionsObserver.TestAndSet(null);
            Assert.IsNull(result);
        }
Example #15
0
 protected void AssertImpression(KeyImpression impressionExpected, List <ImpressionData> sentImpressions)
 {
     Assert.IsTrue(sentImpressions
                   .Where(si => impressionExpected.bucketingKey == si.B)
                   .Where(si => impressionExpected.changeNumber == si.C)
                   .Where(si => impressionExpected.keyName == si.K)
                   .Where(si => impressionExpected.label == si.R)
                   .Where(si => impressionExpected.treatment == si.T)
                   .Any());
 }
Example #16
0
            public void Log(KeyImpression impression)
            {
                //To simulate retry attemps before success
                for (int i = 1; i <= 100; i++)
                {
                    Thread.Sleep(100);
                }

                list.Add(impression);
            }
Example #17
0
 protected void AssertImpression(KeyImpression impressionExpected, List <KeyImpression> sentImpressions)
 {
     Assert.IsTrue(sentImpressions
                   .Where(si => impressionExpected.bucketingKey == si.bucketingKey)
                   .Where(si => impressionExpected.changeNumber == si.changeNumber)
                   .Where(si => impressionExpected.keyName == si.keyName)
                   .Where(si => impressionExpected.label == si.label)
                   .Where(si => impressionExpected.treatment == si.treatment)
                   .Any());
 }
Example #18
0
        public void Works()
        {
            var impressionHasher = new ImpressionHasher();

            var impression = new KeyImpression
            {
                feature      = "someFeature",
                keyName      = "someKeyName",
                treatment    = "someTreatment",
                changeNumber = 3245463,
                label        = "someLabel"
            };

            var impression2 = new KeyImpression
            {
                feature      = "someFeature",
                keyName      = "someKeyName",
                treatment    = "otherTreatment",
                changeNumber = 3245463,
                label        = "someLabel"
            };

            var result  = impressionHasher.Process(impression);
            var result2 = impressionHasher.Process(impression2);

            Assert.AreNotEqual(result, result2);

            impression2.keyName = "otherKeyName";
            var result3 = impressionHasher.Process(impression2);

            Assert.AreNotEqual(result2, result3);

            impression2.feature = "otherFeature";
            var result4 = impressionHasher.Process(impression2);

            Assert.AreNotEqual(result3, result4);

            impression2.treatment = "treatment";
            var result5 = impressionHasher.Process(impression2);

            Assert.AreNotEqual(result4, result5);

            impression2.label = "otherLabel";
            var result6 = impressionHasher.Process(impression2);

            Assert.AreNotEqual(result5, result6);

            impression2.changeNumber = 888755;
            var result7 = impressionHasher.Process(impression2);

            Assert.AreNotEqual(result6, result7);
        }
Example #19
0
        protected void RecordStats(Key key, string feature, long?changeNumber, string label, long start, string treatment, string operation, Stopwatch clock)
        {
            if (metricsLog != null)
            {
                metricsLog.Time(SdkGetTreatment, clock.ElapsedMilliseconds);
            }

            if (impressionListener != null)
            {
                KeyImpression impression = BuildImpression(key.matchingKey, feature, treatment, start, changeNumber, LabelsEnabled ? label : null, key.bucketingKeyHadValue ? key.bucketingKey : null);
                impressionListener.Log(impression);
            }
        }
        public void LogSuccessfullyAndSendImpressions()
        {
            //Act
            _treatmentLog.Start();
            var impression = new KeyImpression()
            {
                keyName = "GetTreatment", feature = "test", treatment = "on", time = 7000, changeNumber = 1, label = "test-label"
            };

            _treatmentLog.Log(impression);

            //Assert
            Thread.Sleep(2000);
            _apiClientMock.Verify(x => x.SendBulkImpressions(It.Is <List <KeyImpression> >(list => list.Count == 1)));
        }
Example #21
0
        public KeyImpression BuildImpression(string matchingKey, string feature, string treatment, long time, long?changeNumber, string label, string bucketingKey)
        {
            var impression = new KeyImpression(matchingKey, feature, treatment, time, changeNumber, label, bucketingKey);

            if (_addPreviousTime && _impressionsObserver != null)
            {
                impression.previousTime = _impressionsObserver.TestAndSet(impression);
            }

            if (_optimized)
            {
                _impressionsCounter.Inc(feature, time);
            }

            return(impression);
        }
Example #22
0
        public void LogSuccessfully()
        {
            //Arrange
            var impressionsCache = new Mock <IImpressionsCache>();
            var treatmentLog     = new RedisTreatmentLog(impressionsCache.Object);

            //Act
            var impression = new KeyImpression()
            {
                keyName = "GetTreatment", feature = "test", treatment = "on", time = 7000, changeNumber = 1, label = "test"
            };

            treatmentLog.Log(impression);

            //Assert
            Thread.Sleep(1000);
            impressionsCache.Verify(mock => mock.AddImpression(It.IsAny <KeyImpression>()), Times.Once());
        }
Example #23
0
        public void LogSuccessfullyUsingBucketingKey()
        {
            //Arrange
            var impressionsCache = new Mock <IImpressionsCache>();
            var treatmentLog     = new RedisTreatmentLog(impressionsCache.Object);

            //Act
            Key key        = new Key(bucketingKey: "a", matchingKey: "testkey");
            var impression = new KeyImpression()
            {
                keyName = key.matchingKey, feature = "test", treatment = "on", time = 7000, changeNumber = 1, label = "test-label", bucketingKey = key.bucketingKey
            };

            treatmentLog.Log(impression);
            //Assert
            Thread.Sleep(1000);
            impressionsCache.Verify(mock => mock.AddImpression(It.Is <KeyImpression>(p => p.keyName == key.matchingKey && p.feature == "test" && p.treatment == "on" && p.time == 7000 && p.changeNumber == 1 && p.label == "test-label" && p.bucketingKey == key.bucketingKey)), Times.Once());
        }
Example #24
0
        public void LogSuccessfullyAndSendImpressions()
        {
            //Arrange
            var apiClientMock    = new Mock <ITreatmentSdkApiClient>();
            var queue            = new BlockingQueue <KeyImpression>(10);
            var impressionsCache = new InMemoryImpressionsCache(queue);
            var treatmentLog     = new SelfUpdatingTreatmentLog(apiClientMock.Object, 1, impressionsCache, 10);

            //Act
            treatmentLog.Start();
            var impression = new KeyImpression()
            {
                keyName = "GetTreatment", feature = "test", treatment = "on", time = 7000, changeNumber = 1, label = "test-label"
            };

            treatmentLog.Log(impression);

            //Assert
            Thread.Sleep(2000);
            apiClientMock.Verify(x => x.SendBulkImpressions(It.IsAny <string>()));
        }
Example #25
0
 public void Log(KeyImpression impression)
 {
     try
     {
         //This task avoids waiting to fire and forget
         //all worker's tasks in the main thread
         var listenerTask =
             new Task(() =>
         {
             foreach (IImpressionListener worker in workers)
             {
                 try
                 {
                     //This task makes worker.Log() run independently
                     //and avoid one worker to block another.
                     var logTask =
                         new Task(() =>
                     {
                         var stopwatch = Stopwatch.StartNew();
                         worker.Log(impression);
                         stopwatch.Stop();
                         Logger.Info(worker.GetType() + " took " + stopwatch.ElapsedMilliseconds + " milliseconds");
                     });
                     logTask.Start();
                 }
                 catch (Exception e)
                 {
                     Logger.Error("Exception performing Log with worker. ", e);
                 }
             }
         });
         listenerTask.Start();
     }
     catch (Exception e)
     {
         Logger.Error("Exception creating Log task. ", e);
     }
 }
Example #26
0
        public void FetchAllAndClearWithNullQueue()
        {
            //Arrange
            var cache      = new InMemorySimpleCache <KeyImpression>(null);
            var impression = new KeyImpression {
                feature = "test", changeNumber = 100, keyName = "date", label = "testdate", time = 10000000
            };
            var impression2 = new KeyImpression {
                feature = "test2", changeNumber = 100, keyName = "date", label = "testdate", time = 10000000
            };

            cache.AddItems(new List <KeyImpression> {
                impression
            });
            cache.AddItems(new List <KeyImpression> {
                impression2
            });

            //Act
            var result = cache.FetchAllAndClear();

            //Assert
            Assert.IsNull(result);
        }
Example #27
0
 public void Log(KeyImpression impression)
 {
     impressionsCache.AddImpression(impression);
 }
Example #28
0
 public bool ShouldQueueImpression(KeyImpression impression)
 {
     return(impression.previousTime == null || (ImpressionsHelper.TruncateTimeFrame(impression.previousTime.Value) != ImpressionsHelper.TruncateTimeFrame(impression.time)));
 }
        public ulong Process(KeyImpression impression)
        {
            var key = $"{UnknowIfNull(impression.keyName)}:{UnknowIfNull(impression.feature)}:{UnknowIfNull(impression.treatment)}:{UnknowIfNull(impression.label)}:{ZeroIfNull(impression.changeNumber)}";

            return(Hash(key, 0));
        }
Example #30
0
 public void Log(KeyImpression impression)
 {
     list.Add(impression);
 }