Skip to content

[FSSDK-10265] fix: UPS Lookup & Save during batched Decide #374

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
963fc07
chore: updated during Rider upgrade
mikechu-optimizely Oct 4, 2024
d0f59b6
feat: call UPS once during batch decideForKeys or decideAll
mikechu-optimizely Oct 4, 2024
14dface
revert: SaveVariation to include userProfile
mikechu-optimizely Oct 4, 2024
66708d8
doc: fix param
mikechu-optimizely Oct 4, 2024
aa0d018
Merge branch 'master' into mike/FSSDK-10265-ups-during-batch-decide
mikechu-optimizely Oct 4, 2024
dd072b9
test: fix hacked tests
mikechu-optimizely Oct 4, 2024
f9f3f3f
revert: auto-formatting
mikechu-optimizely Oct 4, 2024
b43e10f
refactor: SaveToUserProfileService for simplicity
mikechu-optimizely Oct 4, 2024
0dd1b74
revert: formatting
mikechu-optimizely Oct 4, 2024
2b17438
bug: only SaveToUserProfileService if batch is finishing
mikechu-optimizely Oct 7, 2024
c9047a0
test: WIP add coverage for single `Lookup` & `Save` via USP
mikechu-optimizely Oct 7, 2024
dfe1367
refactor: less movement of code as the ref implementation
mikechu-optimizely Oct 8, 2024
57c1ccd
Revert "refactor: less movement of code as the ref implementation"
mikechu-optimizely Oct 8, 2024
9ca271c
test: finish coverage
mikechu-optimizely Oct 8, 2024
c97f36e
Update OptimizelySDK.Tests/OptimizelyUserContextTest.cs
mikechu-optimizely Oct 14, 2024
5b7e5ae
fix: reset _userProfile after batch
mikechu-optimizely Oct 16, 2024
c6889e8
test: add content verification of UPS Save()
mikechu-optimizely Oct 16, 2024
2f46b18
Merge remote-tracking branch 'origin/mike/FSSDK-10265-ups-during-batc…
mikechu-optimizely Oct 16, 2024
54a2dc2
ci: stop CI run if Draft PR = save GH runner costs
mikechu-optimizely Oct 17, 2024
9f2f471
feat: WIP better way to handle loading & saving for UPS
mikechu-optimizely Oct 17, 2024
73658f6
ci: better error echoed
mikechu-optimizely Oct 17, 2024
80e73d4
test: add coverage
mikechu-optimizely Oct 17, 2024
236728b
revert: doc differences
mikechu-optimizely Oct 17, 2024
d6258f1
fix: WIP tests & code under tests
mikechu-optimizely Oct 17, 2024
9c6e9bb
fix: for GetVariation & Activate never use cached user profile
mikechu-optimizely Oct 18, 2024
49f9584
test: corrections
mikechu-optimizely Oct 18, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion .github/workflows/csharp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,20 @@ on:
branches: [ master ]

jobs:
failOnDraftPullRequest:
name: Fail If Draft Pull Request
if: github.event.pull_request.draft == true
runs-on: ubuntu-latest
steps:
- name: Fails Draft pull request.
run: |
echo "Draft pull requests should not trigger CI. Please mark the pull request as Ready for review to continue."
exit 1

lintCodebase:
name: Lint Codebase
needs: [ failOnDraftPullRequest ]
runs-on: ubuntu-latest
name: Lint Codebase
steps:
- name: Checkout code
uses: actions/checkout@v3
Expand Down
10 changes: 5 additions & 5 deletions OptimizelySDK.Tests/DecisionServiceTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -700,7 +700,7 @@ public void TestGetVariationForFeatureExperimentGivenNonMutexGroupAndUserNotBuck

DecisionServiceMock.
Setup(ds => ds.GetVariation(multiVariateExp, OptimizelyUserContextMock.Object,
ProjectConfig, null)).
ProjectConfig, It.IsAny<OptimizelyDecideOption[]>(), It.IsAny<bool>())).
Returns<Variation>(null);
var featureFlag = ProjectConfig.GetFeatureFlagFromKey("multi_variate_feature");

Expand Down Expand Up @@ -736,7 +736,7 @@ public void TestGetVariationForFeatureExperimentGivenNonMutexGroupAndUserIsBucke
DecisionServiceMock.Setup(ds => ds.GetVariation(
ProjectConfig.GetExperimentFromKey("test_experiment_multivariate"),
OptimizelyUserContextMock.Object, ProjectConfig,
It.IsAny<OptimizelyDecideOption[]>())).
It.IsAny<OptimizelyDecideOption[]>(), It.IsAny<bool>())).
Returns(variation);

var featureFlag = ProjectConfig.GetFeatureFlagFromKey("multi_variate_feature");
Expand Down Expand Up @@ -771,7 +771,7 @@ public void TestGetVariationForFeatureExperimentGivenMutexGroupAndUserIsBucketed
DecisionServiceMock.
Setup(ds =>
ds.GetVariation(ProjectConfig.GetExperimentFromKey("group_experiment_1"),
OptimizelyUserContextMock.Object, ProjectConfig)).
OptimizelyUserContextMock.Object, ProjectConfig, It.IsAny<OptimizelyDecideOption[]>(), It.IsAny<bool>())).
Returns(variation);

var featureFlag = ProjectConfig.GetFeatureFlagFromKey("boolean_feature");
Expand All @@ -795,7 +795,7 @@ public void TestGetVariationForFeatureExperimentGivenMutexGroupAndUserNotBuckete
DecisionServiceMock.
Setup(ds => ds.GetVariation(It.IsAny<Experiment>(),
It.IsAny<OptimizelyUserContext>(), ProjectConfig,
It.IsAny<OptimizelyDecideOption[]>())).
It.IsAny<OptimizelyDecideOption[]>(), It.IsAny<bool>())).
Returns(Result<Variation>.NullResult(null));

var featureFlag = ProjectConfig.GetFeatureFlagFromKey("boolean_feature");
Expand Down Expand Up @@ -1311,7 +1311,7 @@ public void TestGetVariationForFeatureWhenTheUserIsBuckedtedInBothExperimentAndR

DecisionServiceMock.Setup(ds => ds.GetVariation(experiment,
OptimizelyUserContextMock.Object, ProjectConfig,
It.IsAny<OptimizelyDecideOption[]>())).
It.IsAny<OptimizelyDecideOption[]>(), It.IsAny<bool>())).
Returns(variation);
var actualDecision = DecisionServiceMock.Object.GetVariationForFeatureExperiment(
featureFlag, OptimizelyUserContextMock.Object, userAttributes, ProjectConfig,
Expand Down
73 changes: 42 additions & 31 deletions OptimizelySDK.Tests/OptimizelyTest.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2017-2023, Optimizely
* Copyright 2017-2024, Optimizely
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -1394,19 +1394,19 @@ public void TestForcedVariationPreceedsUserProfile()
LoggerMock.Verify(
l => l.Log(LogLevel.INFO,
"No previously activated variation of experiment \"etag1\" for user \"testUser3\" found in user profile."),
Times.Exactly(2));
Times.Once);
LoggerMock.Verify(
l => l.Log(LogLevel.DEBUG,
"Assigned bucket [4969] to user [testUser3] with bucketing ID [testUser3]."),
Times.Exactly(2));
Times.Once);
LoggerMock.Verify(
l => l.Log(LogLevel.INFO,
"User [testUser3] is in variation [vtag2] of experiment [etag1]."),
Times.Exactly(2));
Times.Once);
LoggerMock.Verify(
l => l.Log(LogLevel.INFO,
"Saved variation \"277\" of experiment \"223\" for user \"testUser3\"."),
Times.Exactly(2));
Times.Once);
LoggerMock.Verify(
l => l.Log(LogLevel.DEBUG,
"Set variation \"276\" for experiment \"223\" and user \"testUser3\" in the forced variation map."),
Expand Down Expand Up @@ -3395,8 +3395,9 @@ public void TestActivateListener(UserAttributes userAttributes)
mockUserContext.Setup(ouc => ouc.GetUserId()).Returns(TestUserId);

DecisionServiceMock.Setup(ds => ds.GetVariation(experiment,
It.IsAny<OptimizelyUserContext>(), It.IsAny<ProjectConfig>()))
.Returns(variation);
It.IsAny<OptimizelyUserContext>(), It.IsAny<ProjectConfig>(),
It.IsAny<OptimizelyDecideOption[]>(), It.IsAny<bool>())).
Returns(variation);
DecisionServiceMock.Setup(ds => ds.GetVariationForFeature(featureFlag,
It.IsAny<OptimizelyUserContext>(), It.IsAny<ProjectConfig>()))
.Returns(decision);
Expand Down Expand Up @@ -3509,9 +3510,10 @@ public void TestTrackListener(UserAttributes userAttributes, EventTags eventTags
ErrorHandlerMock.Object, LoggerMock.Object);
mockUserContext.Setup(ouc => ouc.GetUserId()).Returns(TestUserId);

DecisionServiceMock
.Setup(ds => ds.GetVariation(experiment, It.IsAny<OptimizelyUserContext>(), Config))
.Returns(variation);
DecisionServiceMock.Setup(ds => ds.GetVariation(experiment,
It.IsAny<OptimizelyUserContext>(), Config, It.IsAny<OptimizelyDecideOption[]>(),
It.IsAny<bool>())).
Returns(variation);

// Adding notification listeners.
var notificationType = NotificationCenter.NotificationType.Track;
Expand Down Expand Up @@ -3565,9 +3567,10 @@ public void TestActivateSendsDecisionNotificationWithActualVariationKey()
It.IsAny<string>(),
It.IsAny<UserAttributes>(), It.IsAny<Dictionary<string, object>>()));

DecisionServiceMock
.Setup(ds => ds.GetVariation(experiment, It.IsAny<OptimizelyUserContext>(), Config))
.Returns(variation);
DecisionServiceMock.Setup(ds => ds.GetVariation(experiment,
It.IsAny<OptimizelyUserContext>(), Config, It.IsAny<OptimizelyDecideOption[]>(),
It.IsAny<bool>())).
Returns(variation);

var optly = Helper.CreatePrivateOptimizely();
optly.SetFieldOrProperty("ProjectConfigManager", ConfigManager);
Expand Down Expand Up @@ -3622,9 +3625,10 @@ public void
It.IsAny<string>(),
It.IsAny<UserAttributes>(), It.IsAny<Dictionary<string, object>>()));

DecisionServiceMock
.Setup(ds => ds.GetVariation(experiment, It.IsAny<OptimizelyUserContext>(), Config))
.Returns(variation);
DecisionServiceMock.Setup(ds => ds.GetVariation(experiment,
It.IsAny<OptimizelyUserContext>(), Config, It.IsAny<OptimizelyDecideOption[]>(),
It.IsAny<bool>())).
Returns(variation);

var optly = Helper.CreatePrivateOptimizely();
optly.SetFieldOrProperty("ProjectConfigManager", ConfigManager);
Expand Down Expand Up @@ -3666,8 +3670,9 @@ public void TestActivateSendsDecisionNotificationWithNullVariationKey()

DecisionServiceMock.Setup(ds => ds.GetVariation(experiment,
It.IsAny<OptimizelyUserContext>(),
It.IsAny<ProjectConfig>(), null))
.Returns(Result<Variation>.NullResult(null));
It.IsAny<ProjectConfig>(), It.IsAny<OptimizelyDecideOption[]>(),
It.IsAny<bool>())).
Returns(Result<Variation>.NullResult(null));

optStronglyTyped.NotificationCenter.AddNotification(
NotificationCenter.NotificationType.Decision,
Expand Down Expand Up @@ -3727,9 +3732,10 @@ public void TestGetVariationSendsDecisionNotificationWithActualVariationKey()
ErrorHandlerMock.Object, LoggerMock.Object);
mockUserContext.Setup(ouc => ouc.GetUserId()).Returns(TestUserId);

DecisionServiceMock
.Setup(ds => ds.GetVariation(experiment, It.IsAny<OptimizelyUserContext>(), Config))
.Returns(variation);
DecisionServiceMock.Setup(ds => ds.GetVariation(experiment,
It.IsAny<OptimizelyUserContext>(), Config, It.IsAny<OptimizelyDecideOption[]>(),
It.IsAny<bool>())).
Returns(variation);

optStronglyTyped.NotificationCenter.AddNotification(
NotificationCenter.NotificationType.Decision,
Expand Down Expand Up @@ -3788,9 +3794,10 @@ public void
ErrorHandlerMock.Object, LoggerMock.Object);
mockUserContext.Setup(ouc => ouc.GetUserId()).Returns(TestUserId);

DecisionServiceMock
.Setup(ds => ds.GetVariation(experiment, It.IsAny<OptimizelyUserContext>(), Config))
.Returns(variation);
DecisionServiceMock.
Setup(ds => ds.GetVariation(experiment, It.IsAny<OptimizelyUserContext>(), Config
, It.IsAny<OptimizelyDecideOption[]>(), It.IsAny<bool>())).
Returns(variation);

optStronglyTyped.NotificationCenter.AddNotification(
NotificationCenter.NotificationType.Decision,
Expand Down Expand Up @@ -3828,8 +3835,9 @@ public void TestGetVariationSendsDecisionNotificationWithNullVariationKey()
It.IsAny<UserAttributes>(), It.IsAny<Dictionary<string, object>>()));

DecisionServiceMock.Setup(ds => ds.GetVariation(It.IsAny<Experiment>(),
It.IsAny<OptimizelyUserContext>(), It.IsAny<ProjectConfig>()))
.Returns(Result<Variation>.NullResult(null));
It.IsAny<OptimizelyUserContext>(), It.IsAny<ProjectConfig>()
, It.IsAny<OptimizelyDecideOption[]>(), It.IsAny<bool>())).
Returns(Result<Variation>.NullResult(null));
//DecisionServiceMock.Setup(ds => ds.GetVariation(experiment, TestUserId, Config, null)).Returns(Result<Variation>.NullResult(null));

optStronglyTyped.NotificationCenter.AddNotification(
Expand Down Expand Up @@ -3875,8 +3883,9 @@ public void
It.IsAny<UserAttributes>(), It.IsAny<Dictionary<string, object>>()));

DecisionServiceMock.Setup(ds => ds.GetVariation(experiment,
It.IsAny<OptimizelyUserContext>(), ConfigManager.GetConfig(), null))
.Returns(variation);
It.IsAny<OptimizelyUserContext>(), ConfigManager.GetConfig()
, It.IsAny<OptimizelyDecideOption[]>(), It.IsAny<bool>())).
Returns(variation);

var optly = Helper.CreatePrivateOptimizely();
var optStronglyTyped = optly.GetObject() as Optimizely;
Expand Down Expand Up @@ -3936,8 +3945,9 @@ public void
It.IsAny<UserAttributes>(), It.IsAny<Dictionary<string, object>>()));

DecisionServiceMock.Setup(ds =>
ds.GetVariation(experiment, It.IsAny<OptimizelyUserContext>(), Config, null))
.Returns(variation);
ds.GetVariation(experiment, It.IsAny<OptimizelyUserContext>(), Config
, It.IsAny<OptimizelyDecideOption[]>(), It.IsAny<bool>())).
Returns(variation);

var optly = Helper.CreatePrivateOptimizely();
var optStronglyTyped = optly.GetObject() as Optimizely;
Expand Down Expand Up @@ -5322,7 +5332,8 @@ public void TestGetAllFeatureVariablesReturnsNullScenarios()

LoggerMock.Verify(
log => log.Log(LogLevel.ERROR,
"Optimizely instance is not valid, failing getAllFeatureVariableValues call. type"),
"Optimizely instance is not valid, failing getAllFeatureVariableValues call. type")
,
Times.Once);
}

Expand Down
Loading
Loading