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)); }
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); }
public void AddImpression(KeyImpression impression) { var key = redisKeyPrefix + impressionKeyPrefix + impression.feature; var impressionJson = JsonConvert.SerializeObject(impression); redisAdapter.SAdd(key, impressionJson); }
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); }
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); }
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); } }
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); }
public void AddImpression(KeyImpression impression) { if (queue != null) { queue.Enqueue(impression); } }
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); }
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); }
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); }
public void Log(KeyImpression impression) { if (queue.HasReachedMaxSize()) { queue.Dequeue(); } queue.Enqueue(impression); }
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); }
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()); }
public void Log(KeyImpression impression) { //To simulate retry attemps before success for (int i = 1; i <= 100; i++) { Thread.Sleep(100); } list.Add(impression); }
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()); }
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); }
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))); }
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); }
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()); }
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()); }
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>())); }
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); } }
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); }
public void Log(KeyImpression impression) { impressionsCache.AddImpression(impression); }
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)); }
public void Log(KeyImpression impression) { list.Add(impression); }