diff --git a/src/ConfigCat.Client.Tests/ConfigCat.Client.Tests.csproj b/src/ConfigCat.Client.Tests/ConfigCat.Client.Tests.csproj index 8333afbe..f34e4957 100644 --- a/src/ConfigCat.Client.Tests/ConfigCat.Client.Tests.csproj +++ b/src/ConfigCat.Client.Tests/ConfigCat.Client.Tests.csproj @@ -11,9 +11,36 @@ ..\ConfigCatClient.snk - - USE_NEWTONSOFT_JSON - + + + + USE_NEWTONSOFT_JSON + + + + + + + + + + + + + + + + + + + + + + + + @@ -22,16 +49,10 @@ - - - - diff --git a/src/ConfigCat.Client.Tests/EvaluationLogTests.cs b/src/ConfigCat.Client.Tests/EvaluationLogTests.cs index 6f15897d..808ba8e8 100644 --- a/src/ConfigCat.Client.Tests/EvaluationLogTests.cs +++ b/src/ConfigCat.Client.Tests/EvaluationLogTests.cs @@ -7,6 +7,7 @@ using ConfigCat.Client.Tests.Helpers; using ConfigCat.Client.Utils; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; #if NET45 using Newtonsoft.Json; @@ -175,6 +176,16 @@ public void SemVerValidationTests(string testSetName, string? sdkKey, string? ba RunTest(testSetName, sdkKey, baseUrlOrOverrideFileName, key, defaultValue, userObject, expectedReturnValue, expectedLogFileName); } + private static IEnumerable GetListTruncationTests() => GetTests("list_truncation"); + + [DataTestMethod] + [DynamicData(nameof(GetListTruncationTests), DynamicDataSourceType.Method)] + public void ListTruncationTests(string testSetName, string? sdkKey, string? baseUrlOrOverrideFileName, + string key, string? defaultValue, string userObject, string? expectedReturnValue, string expectedLogFileName) + { + RunTest(testSetName, sdkKey, baseUrlOrOverrideFileName, key, defaultValue, userObject, expectedReturnValue, expectedLogFileName); + } + private static IEnumerable GetTests(string testSetName) { var filePath = Path.Combine(TestDataRootPath, testSetName + ".json"); @@ -197,36 +208,6 @@ public void SemVerValidationTests(string testSetName, string? sdkKey, string? ba } } - [TestMethod] - public void ComparisonValueListTruncation() - { - var config = new ConfigLocation.LocalFile("data", "test_list_truncation.json").FetchConfig(); - - var logEvents = new List(); - var logger = LoggingHelper.CreateCapturingLogger(logEvents); - - var evaluator = new RolloutEvaluator(logger); - var evaluationDetails = evaluator.Evaluate(config.Settings, "key1", (bool?)null, new User("12"), remoteConfig: null, logger); - var actualReturnValue = evaluationDetails.Value; - - Assert.AreEqual(true, actualReturnValue); - Assert.AreEqual(1, logEvents.Count); - - var expectedLogLines = new[] - { - "INFO [5000] Evaluating 'key1' for User '{\"Identifier\":\"12\"}'", - " Evaluating targeting rules and applying the first match if any:", - " - IF User.Identifier CONTAINS ANY OF ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'] => true", - " AND User.Identifier CONTAINS ANY OF ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10' ... <1 more value>] => true", - " AND User.Identifier CONTAINS ANY OF ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10' ... <2 more values>] => true", - " THEN 'True' => MATCH, applying rule", - " Returning 'True'.", - }; - - var evt = logEvents[0]; - Assert.AreEqual(string.Join(Environment.NewLine, expectedLogLines), FormatLogEvent(ref evt)); - } - private static void RunTest(string testSetName, string? sdkKey, string? baseUrlOrOverrideFileName, string key, string? defaultValue, string? userObject, string? expectedReturnValue, string expectedLogFileName) { var defaultValueParsed = defaultValue?.Deserialize()!.ToSettingValue(out var settingType).GetValue(); @@ -320,4 +301,40 @@ public class TestCase public string expectedLog { get; set; } = null!; } #pragma warning restore IDE1006 // Naming Styles + + [DataTestMethod] + [DataRow(LogLevel.Off, false)] + [DataRow(LogLevel.Error, false)] + [DataRow(LogLevel.Warning, false)] + [DataRow(LogLevel.Info, true)] + [DataRow(LogLevel.Debug, true)] + public void EvaluationLogShouldBeBuiltOnlyWhenNecessary(LogLevel logLevel, bool expectedIsLogBuilt) + { + var settings = new ConfigLocation.Cdn("configcat-sdk-1/PKDVCLf-Hq-h-kCzMp-L7Q/AG6C1ngVb0CvM07un6JisQ").FetchConfigCached().Settings; + + var logEvents = new List(); + var logger = LoggingHelper.CreateCapturingLogger(logEvents, logLevel); + + var evaluator = new RolloutEvaluator(logger); + + var actualIsLogBuilt = false; + var evaluatorMock = new Mock(); + evaluatorMock + .Setup(e => e.Evaluate(ref It.Ref.IsAny)) + .Returns((ref EvaluateContext ctx) => + { + var result = evaluator.Evaluate(ref ctx); + actualIsLogBuilt = ctx.LogBuilder is not null; + return result; + }); + + var evaluationResult = evaluatorMock.Object.Evaluate(settings, "bool30TrueAdvancedRules", defaultValue: null, user: null, remoteConfig: null, logger); + Assert.IsFalse(evaluationResult.IsDefaultValue); + Assert.IsTrue(evaluationResult.Value); + + Assert.AreEqual(actualIsLogBuilt, expectedIsLogBuilt); + + Assert.AreEqual(logLevel >= LogLevel.Warning, logEvents.Any(evt => evt is { Level: LogLevel.Warning, EventId.Id: 3001 })); + Assert.AreEqual(expectedIsLogBuilt, logEvents.Any(evt => evt is { Level: LogLevel.Info, EventId.Id: 5000 })); + } } diff --git a/src/ConfigCat.Client.Tests/data/evaluationlog/_overrides/test_list_truncation.json b/src/ConfigCat.Client.Tests/data/evaluationlog/_overrides/test_list_truncation.json new file mode 100644 index 00000000..12cf9e5e --- /dev/null +++ b/src/ConfigCat.Client.Tests/data/evaluationlog/_overrides/test_list_truncation.json @@ -0,0 +1,83 @@ +{ + "p": { + "u": "https://cdn-global.configcat.com", + "r": 0, + "s": "test-salt" + }, + "f": { + "booleanKey1": { + "t": 0, + "v": { + "b": false + }, + "r": [ + { + "c": [ + { + "t": { + "a": "Identifier", + "c": 2, + "l": [ + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10" + ] + } + }, + { + "t": { + "a": "Identifier", + "c": 2, + "l": [ + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10", + "11" + ] + } + }, + { + "t": { + "a": "Identifier", + "c": 2, + "l": [ + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10", + "11", + "12" + ] + } + } + ], + "s": { + "v": { + "b": true + } + } + } + ] + } + } +} diff --git a/src/ConfigCat.Client.Tests/data/evaluationlog/list_truncation.json b/src/ConfigCat.Client.Tests/data/evaluationlog/list_truncation.json new file mode 100644 index 00000000..64e94262 --- /dev/null +++ b/src/ConfigCat.Client.Tests/data/evaluationlog/list_truncation.json @@ -0,0 +1,14 @@ +{ + "jsonOverride": "test_list_truncation.json", + "tests": [ + { + "key": "booleanKey1", + "defaultValue": false, + "user": { + "Identifier": "12" + }, + "returnValue": true, + "expectedLog": "list_truncation.txt" + } + ] +} diff --git a/src/ConfigCat.Client.Tests/data/evaluationlog/list_truncation/list_truncation.txt b/src/ConfigCat.Client.Tests/data/evaluationlog/list_truncation/list_truncation.txt new file mode 100644 index 00000000..3d339b82 --- /dev/null +++ b/src/ConfigCat.Client.Tests/data/evaluationlog/list_truncation/list_truncation.txt @@ -0,0 +1,7 @@ +INFO [5000] Evaluating 'booleanKey1' for User '{"Identifier":"12"}' + Evaluating targeting rules and applying the first match if any: + - IF User.Identifier CONTAINS ANY OF ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'] => true + AND User.Identifier CONTAINS ANY OF ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10' ... <1 more value>] => true + AND User.Identifier CONTAINS ANY OF ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10' ... <2 more values>] => true + THEN 'True' => MATCH, applying rule + Returning 'True'. diff --git a/src/ConfigCat.Client.Tests/data/test_list_truncation.json b/src/ConfigCat.Client.Tests/data/test_list_truncation.json deleted file mode 100644 index a665062b..00000000 --- a/src/ConfigCat.Client.Tests/data/test_list_truncation.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "f": { - "key1": { - "t": 0, - "v": { "b": false }, - "r": [ - { - "c": [ - { - "t": { - "a": "Identifier", - "c": 2, - "l": [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" ] - } - }, - { - "t": { - "a": "Identifier", - "c": 2, - "l": [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11" ] - } - }, - { - "t": { - "a": "Identifier", - "c": 2, - "l": [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12" ] - } - } - ], - "s": { "v": { "b": true } } - } - ] - } - } -}