Skip to content

Commit

Permalink
Add more evaluation log tests
Browse files Browse the repository at this point in the history
  • Loading branch information
adams85 committed Oct 6, 2023
1 parent fc231c4 commit c4aef60
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 75 deletions.
39 changes: 30 additions & 9 deletions src/ConfigCat.Client.Tests/ConfigCat.Client.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,36 @@
<AssemblyOriginatorKeyFile>..\ConfigCatClient.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>

<PropertyGroup Condition=" '$(TargetFramework)' == 'net45' ">
<DefineConstants>USE_NEWTONSOFT_JSON</DefineConstants>
</PropertyGroup>
<Choose>
<When Condition="'$(TargetFramework)' == 'net45'">
<PropertyGroup>
<DefineConstants>USE_NEWTONSOFT_JSON</DefineConstants>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.10" />
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
</ItemGroup>
</When>

<When Condition="'$(TargetFramework)' == 'net461'">
<ItemGroup>
<!-- DynamicData matrix tests won't show up in VS 2022 using MSTest.TestAdapter v2.2.10.
It seems we'd need v3.x to make that work. But v3.x supports .NET 4.6.2+ only... :S
TODO: upgrade to v3.x when when we drop support for .NET 4.6.1 and earlier. -->
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.10" />
</ItemGroup>
</When>

<Otherwise>
<ItemGroup>
<PackageReference Include="MSTest.TestAdapter" Version="3.1.1" />
<PackageReference Include="MSTest.TestFramework" Version="3.1.1" />
</ItemGroup>
</Otherwise>
</Choose>

<ItemGroup>
<PackageReference Include="coverlet.collector" Version="3.1.2">
Expand All @@ -22,16 +49,10 @@
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
<PackageReference Include="Moq" Version="4.16.1" />
<!-- DynamicData matrix tests won't show up in VS 2022 using MSTest.TestAdapter v2.2.10.
It seems we'd need v3.x to make that work. But v3.x supports .NET 4.6.2+ only... :S
TODO: upgrade to v3.x when when we drop support for .NET 4.6.1 and earlier. -->
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.10" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
<PackageReference Include="System.Net.Http" Version="4.3.4" />
<!--Do not remove this reference, it was added due to a SNYK security report-->
<PackageReference Include="System.Text.RegularExpressions" Version="4.3.1" />
<PackageReference Include="System.ValueTuple" Version="4.5.0" Condition="'$(TargetFramework)' == 'net45'" />
</ItemGroup>

<ItemGroup>
Expand Down
77 changes: 47 additions & 30 deletions src/ConfigCat.Client.Tests/EvaluationLogTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<object?[]> 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<object?[]> GetTests(string testSetName)
{
var filePath = Path.Combine(TestDataRootPath, testSetName + ".json");
Expand All @@ -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<LogEvent>();
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<JsonValue>()!.ToSettingValue(out var settingType).GetValue();
Expand Down Expand Up @@ -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<LogEvent>();
var logger = LoggingHelper.CreateCapturingLogger(logEvents, logLevel);

var evaluator = new RolloutEvaluator(logger);

var actualIsLogBuilt = false;
var evaluatorMock = new Mock<IRolloutEvaluator>();
evaluatorMock
.Setup(e => e.Evaluate(ref It.Ref<EvaluateContext>.IsAny))
.Returns((ref EvaluateContext ctx) =>
{
var result = evaluator.Evaluate(ref ctx);
actualIsLogBuilt = ctx.LogBuilder is not null;
return result;
});

var evaluationResult = evaluatorMock.Object.Evaluate<bool?>(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 }));
}
}
Original file line number Diff line number Diff line change
@@ -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
}
}
}
]
}
}
}
14 changes: 14 additions & 0 deletions src/ConfigCat.Client.Tests/data/evaluationlog/list_truncation.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"jsonOverride": "test_list_truncation.json",
"tests": [
{
"key": "booleanKey1",
"defaultValue": false,
"user": {
"Identifier": "12"
},
"returnValue": true,
"expectedLog": "list_truncation.txt"
}
]
}
Original file line number Diff line number Diff line change
@@ -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'.
36 changes: 0 additions & 36 deletions src/ConfigCat.Client.Tests/data/test_list_truncation.json

This file was deleted.

0 comments on commit c4aef60

Please sign in to comment.