Skip to content

Commit 8f19092

Browse files
Mat001claude
andcommitted
Remove Holdouts field from OptimizelyConfig API
Updated Agent to use go-sdk branch that removed the Holdouts field from OptimizelyConfig. This aligns with JavaScript and C# SDKs and fixes FSC test failures. Agent doesn't need holdouts exposed in OptimizelyConfig because: - The /v1/decide endpoint uses go-sdk's decision service which handles holdouts internally through GetHoldoutsForFlag() and GetHoldoutList() methods - OptimizelyConfig is for metadata, not decision-making - Holdout decision logic is already present in go-sdk v2.3.0 Changes: - Updated go.mod to use go-sdk@mpirnovar-fix-activate-endpoint-holdouts - Removed TestConfigIncludesHoldouts test - Removed test_config_with_holdouts and validate_holdout_structure tests - Removed session_override_sdk_key_holdouts fixture - Removed sdk_key_holdouts constant 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent 2cc80ed commit 8f19092

File tree

4 files changed

+1
-136
lines changed

4 files changed

+1
-136
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ require (
1515
github.com/golang-jwt/jwt/v4 v4.5.2
1616
github.com/google/uuid v1.3.1
1717
github.com/lestrrat-go/jwx/v2 v2.0.20
18-
github.com/optimizely/go-sdk/v2 v2.1.1-0.20250930190916-92b83d299b7a
18+
github.com/optimizely/go-sdk/v2 v2.3.1-0.20251212231147-e70a8f37a76a
1919
github.com/orcaman/concurrent-map v1.0.0
2020
github.com/prometheus/client_golang v1.18.0
2121
github.com/rakyll/statik v0.1.7

pkg/handlers/optimizely_config_test.go

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -77,24 +77,6 @@ func (suite *OptimizelyConfigTestSuite) TestConfig() {
7777
suite.Equal(*suite.oc.GetOptimizelyConfig(), actual)
7878
}
7979

80-
func (suite *OptimizelyConfigTestSuite) TestConfigIncludesHoldouts() {
81-
req := httptest.NewRequest("GET", "/config", nil)
82-
rec := httptest.NewRecorder()
83-
suite.mux.ServeHTTP(rec, req)
84-
suite.Equal(http.StatusOK, rec.Code)
85-
86-
// Unmarshal response
87-
var actual config.OptimizelyConfig
88-
err := json.Unmarshal(rec.Body.Bytes(), &actual)
89-
suite.NoError(err)
90-
91-
// Verify holdouts field is present
92-
suite.NotNil(actual.Holdouts, "Holdouts field should be present in config")
93-
94-
// Verify it's an empty array (test datafile has no holdouts)
95-
suite.Empty(actual.Holdouts, "Holdouts should be empty for test datafile")
96-
}
97-
9880
// In order for 'go test' to run this suite, we need to create
9981
// a normal test function and pass our suite to suite.Run
10082
func TestOptimizelyConfigTestSuite(t *testing.T) {

tests/acceptance/test_acceptance/conftest.py

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@
99
# sdk key of the project "Agent Acceptance w ODP", under QA account
1010
sdk_key_odp = "91GuiKYH8ZF1hLLXR7DR1"
1111

12-
# sdk key for holdouts datafile
13-
sdk_key_holdouts = "BLsSFScP7tSY5SCYuKn8c"
14-
1512
@pytest.fixture
1613
def session_obj():
1714
"""
@@ -50,17 +47,6 @@ def session_override_sdk_key(session_obj):
5047
return session_obj
5148

5249

53-
@pytest.fixture(scope='function')
54-
def session_override_sdk_key_holdouts(session_obj):
55-
"""
56-
Override session_obj fixture with holdouts SDK key.
57-
:param session_obj: session fixture object
58-
:return: updated session object
59-
"""
60-
session_obj.headers['X-Optimizely-SDK-Key'] = sdk_key_holdouts
61-
return session_obj
62-
63-
6450
def pytest_addoption(parser):
6551
"""
6652
Adding CLI option to specify host URL to run tests on.

tests/acceptance/test_acceptance/test_config.py

Lines changed: 0 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -505,106 +505,3 @@ def test_config_403(session_override_sdk_key):
505505
'rechecking SDK key), status code: 403 Forbidden'
506506

507507
resp.raise_for_status()
508-
509-
510-
def test_config_includes_holdouts(session_obj):
511-
"""
512-
Test that the config endpoint includes the holdouts field.
513-
Validates the holdouts structure is present even if empty.
514-
:param session_obj: session object
515-
"""
516-
resp = create_and_validate_request_and_response(ENDPOINT_CONFIG, 'get', session_obj)
517-
518-
assert resp.status_code == 200
519-
resp.raise_for_status()
520-
521-
config = resp.json()
522-
523-
# Verify holdouts field exists
524-
assert 'holdouts' in config, "Config response should include 'holdouts' field"
525-
526-
# Verify it's a list
527-
assert isinstance(config['holdouts'], list), "Holdouts should be a list"
528-
529-
# Current datafile has no holdouts, so should be empty
530-
# When datafiles with holdouts are added, this test can be extended
531-
# to validate holdout structure (id, key, audiences, variationsMap)
532-
assert config['holdouts'] == [], "Current datafile should have no holdouts"
533-
534-
535-
def validate_holdout_structure(holdout):
536-
"""
537-
Helper function to validate a single holdout object structure.
538-
:param holdout: holdout object to validate
539-
"""
540-
# Verify required fields exist
541-
assert 'id' in holdout, "Holdout should have 'id' field"
542-
assert 'key' in holdout, "Holdout should have 'key' field"
543-
assert 'audiences' in holdout, "Holdout should have 'audiences' field"
544-
assert 'variationsMap' in holdout, "Holdout should have 'variationsMap' field"
545-
546-
# Verify field types
547-
assert isinstance(holdout['id'], str), "Holdout id should be a string"
548-
assert isinstance(holdout['key'], str), "Holdout key should be a string"
549-
assert isinstance(holdout['audiences'], str), "Holdout audiences should be a string"
550-
assert isinstance(holdout['variationsMap'], dict), "Holdout variationsMap should be a dict"
551-
552-
# Verify variationsMap contains valid variation objects
553-
for variation_key, variation in holdout['variationsMap'].items():
554-
assert isinstance(variation_key, str), "Variation key should be a string"
555-
assert 'id' in variation, "Variation should have 'id' field"
556-
assert 'key' in variation, "Variation should have 'key' field"
557-
assert 'featureEnabled' in variation, "Variation should have 'featureEnabled' field"
558-
assert 'variablesMap' in variation, "Variation should have 'variablesMap' field"
559-
560-
assert isinstance(variation['id'], str), "Variation id should be a string"
561-
assert isinstance(variation['key'], str), "Variation key should be a string"
562-
assert isinstance(variation['featureEnabled'], bool), "Variation featureEnabled should be a bool"
563-
assert isinstance(variation['variablesMap'], dict), "Variation variablesMap should be a dict"
564-
565-
566-
def test_config_with_holdouts(session_override_sdk_key_holdouts):
567-
"""
568-
Test that the config endpoint properly returns holdout data when the datafile contains holdouts.
569-
This test validates the full structure of holdouts including id, key, audiences, and variationsMap.
570-
:param session_override_sdk_key_holdouts: session object with holdouts SDK key
571-
"""
572-
resp = create_and_validate_request_and_response(ENDPOINT_CONFIG, 'get', session_override_sdk_key_holdouts)
573-
574-
assert resp.status_code == 200
575-
resp.raise_for_status()
576-
577-
config = resp.json()
578-
579-
# Verify holdouts field exists and is a list
580-
assert 'holdouts' in config, "Config response should include 'holdouts' field"
581-
assert isinstance(config['holdouts'], list), "Holdouts should be a list"
582-
583-
# Verify we have holdouts data (holdouts_datafile has 4 holdouts)
584-
assert len(config['holdouts']) == 4, f"Expected 4 holdouts, got {len(config['holdouts'])}"
585-
586-
# Validate each holdout structure
587-
for holdout in config['holdouts']:
588-
validate_holdout_structure(holdout)
589-
590-
# Verify specific holdout keys are present
591-
holdout_keys = {h['key'] for h in config['holdouts']}
592-
expected_keys = {'holdout_3', 'holdout_5', 'holdouts_4', 'holdout_6'}
593-
assert holdout_keys == expected_keys, f"Expected holdout keys {expected_keys}, got {holdout_keys}"
594-
595-
# Verify holdout IDs are present
596-
holdout_ids = {h['id'] for h in config['holdouts']}
597-
expected_ids = {'1673112', '1673113', '1673114', '1673115'}
598-
assert holdout_ids == expected_ids, f"Expected holdout IDs {expected_ids}, got {holdout_ids}"
599-
600-
# Verify each holdout has the dummy variation
601-
for holdout in config['holdouts']:
602-
assert 'off' in holdout['variationsMap'], f"Holdout {holdout['key']} should have 'off' variation"
603-
off_variation = holdout['variationsMap']['off']
604-
assert off_variation['id'] == '$opt_dummy_variation_id', "Off variation should have dummy ID"
605-
assert off_variation['featureEnabled'] is False, "Off variation should have featureEnabled=False"
606-
607-
# Verify audiences are properly formatted
608-
for holdout in config['holdouts']:
609-
# Audiences should be a non-empty string containing audience information
610-
assert len(holdout['audiences']) > 0, f"Holdout {holdout['key']} should have audiences"

0 commit comments

Comments
 (0)