protected TreatmentResult GetTreatment(Key key, ParsedSplit split, Dictionary <string, object> attributes, ISplitClient splitClient) { if (!split.killed) { bool inRollout = false; // use the first matching condition foreach (var condition in split.conditions) { if (!inRollout && condition.conditionType == ConditionType.ROLLOUT) { if (split.trafficAllocation < 100) { // bucket ranges from 1-100. var bucket = split.algo == AlgorithmEnum.LegacyHash ? splitter.LegacyBucket(key.bucketingKey, split.trafficAllocationSeed) : splitter.Bucket(key.bucketingKey, split.trafficAllocationSeed); if (bucket > split.trafficAllocation) { return(new TreatmentResult(LabelTrafficAllocationFailed, split.defaultTreatment, split.changeNumber)); } } inRollout = true; } var combiningMatcher = condition.matcher; if (combiningMatcher.Match(key, attributes, splitClient)) { var treatment = splitter.GetTreatment(key.bucketingKey, split.seed, condition.partitions, split.algo); return(new TreatmentResult(condition.label, treatment, split.changeNumber)); } } return(new TreatmentResult(LabelDefaultRule, split.defaultTreatment, split.changeNumber)); } else { return(new TreatmentResult(LabelKilled, split.defaultTreatment, split.changeNumber)); } }
private void VerifyTestFile(string file, string[] sepparator, bool legacy = true) { //Arrange var fileContent = File.ReadAllText(file); var contents = fileContent.Split(sepparator, StringSplitOptions.None); var csv = from line in contents select line.Split(',').ToArray(); var splitter = new Splitter(); bool first = true; var results = new List <string>(); //Act foreach (string[] item in csv) { if (first) { first = false; } else { if (item.Length == 4) { var hash = legacy ? splitter.LegacyHash(item[1], int.Parse(item[0])) : splitter.Hash(item[1], int.Parse(item[0])); var bucket = legacy ? splitter.LegacyBucket(item[1], int.Parse(item[0])) : splitter.Bucket(item[1], int.Parse(item[0])); //Assert Assert.AreEqual(hash, long.Parse(item[2])); Assert.AreEqual(bucket, int.Parse(item[3])); } } } }
protected string GetTreatment(Key key, ParsedSplit split, Dictionary <string, object> attributes, long start, Stopwatch clock, ISplitClient splitClient, bool logMetricsAndImpressions) { if (!split.killed) { bool inRollout = false; // use the first matching condition foreach (ConditionWithLogic condition in split.conditions) { if (!inRollout && condition.conditionType == ConditionType.ROLLOUT) { if (split.trafficAllocation < 100) { // bucket ranges from 1-100. int bucket = split.algo == AlgorithmEnum.LegacyHash ? splitter.LegacyBucket(key.bucketingKey, split.trafficAllocationSeed) : splitter.Bucket(key.bucketingKey, split.trafficAllocationSeed); if (bucket >= split.trafficAllocation) { if (logMetricsAndImpressions) { // If not in traffic allocation, abort and return // default treatment RecordStats(key, split.name, split.changeNumber, LabelTrafficAllocationFailed, start, split.defaultTreatment, SdkGetTreatment, clock); } return(split.defaultTreatment); } } inRollout = true; } var combiningMatcher = condition.matcher; if (combiningMatcher.Match(key, attributes, splitClient)) { var treatment = splitter.GetTreatment(key.bucketingKey, split.seed, condition.partitions, split.algo); if (logMetricsAndImpressions) { //If condition matched, impression label = condition.label RecordStats(key, split.name, split.changeNumber, condition.label, start, treatment, SdkGetTreatment, clock); } return(treatment); } } if (logMetricsAndImpressions) { //If no condition matched, impression label = "no rule matched" RecordStats(key, split.name, split.changeNumber, LabelNoConditionMatched, start, split.defaultTreatment, SdkGetTreatment, clock); } return(split.defaultTreatment); } else { if (logMetricsAndImpressions) { //If split was killed, impression label = "killed" RecordStats(key, split.name, split.changeNumber, LabelKilled, start, split.defaultTreatment, SdkGetTreatment, clock); } return(split.defaultTreatment); } }