diff --git a/tests/Common/FeatureFlags/flag_evaluation_wire.inc b/tests/Common/FeatureFlags/flag_evaluation_wire.inc index 08ef6b7f63..2a2c03e73d 100644 --- a/tests/Common/FeatureFlags/flag_evaluation_wire.inc +++ b/tests/Common/FeatureFlags/flag_evaluation_wire.inc @@ -92,8 +92,11 @@ try { $protectedBytesAbsent = $protectedBytesAbsent && strpos($capture[3], 'ffe-protected-pii-canary@example.test') === false && strpos($capture[3], 'ffe-context-pii-canary@example.test') === false; - if (strpos($capture[3], 'ffe-error-pii-canary@example.test') !== false) { - throw new RuntimeException('raw error text reached the payload'); + foreach (array('ffe-error-pii-canary@example.test', 'ffe-oversized-identity-canary-', + 'oversized-identity-context-canary@example.test') as $canary) { + if (strpos($capture[3], $canary) !== false) { + throw new RuntimeException('omitted evaluation data reached the payload'); + } } // Application attribution is deferred to FFL-3438/FFL-3439. $evaluationIdentityAbsent = $evaluationIdentityAbsent && $payload['context'] === array(); @@ -129,6 +132,23 @@ try { echo 'protected_subject='; var_dump($rows['protected']['targeting_key']); echo 'protected_context_absent='; var_dump(!isset($rows['protected']['context']['evaluation'])); echo 'protected_raw_bytes_absent='; var_dump($protectedBytesAbsent); + foreach (array('oversized-identity', 'oversized-successor') as $flag) { + $row = $rows[$flag]; + if ($row['evaluation_count'] !== 1 || $row['variant']['key'] !== 'blue' + || $row['allocation']['key'] !== 'allocation' + || array_key_exists('error', $row) || array_key_exists('runtime_default_used', $row) + || !is_int($row['timestamp']) || !is_int($row['first_evaluation']) + || !is_int($row['last_evaluation']) || $row['first_evaluation'] > $row['last_evaluation']) { + throw new RuntimeException('oversized identity or its successor lost evaluation dimensions'); + } + } + echo 'oversized_identity_omits_identity_and_context='; + var_dump(!array_key_exists('targeting_key', $rows['oversized-identity']) + && !array_key_exists('context', $rows['oversized-identity'])); + echo 'oversized_identity_successor_retains_context='; + var_dump($rows['oversized-successor']['targeting_key'] === 'normal-successor' + && $rows['oversized-successor']['context']['evaluation'] === array( + 'email' => 'oversized-successor-context-canary@example.test')); echo 'evaluation_times_preserved='; var_dump($rows['timestamped']['evaluation_count'] === 2 && $rows['timestamped']['timestamp'] === 1700000000456 @@ -186,7 +206,9 @@ try { $piiAbsent = true; foreach (array('ffe-protected-pii-canary@example.test', 'ffe-context-pii-canary@example.test', 'ffe-consented-pii-canary@example.test', 'ffe-consented-context-canary@example.test', - 'ffe-error-pii-canary@example.test') as $canary) { + 'ffe-error-pii-canary@example.test', 'ffe-oversized-identity-canary-', + 'oversized-identity-context-canary@example.test', + 'oversized-successor-context-canary@example.test') as $canary) { $piiAbsent = $piiAbsent && !ffeTestStreamContains($diagnostics, $canary) && strpos($stderr, $canary) === false; } diff --git a/tests/Common/FeatureFlags/flag_evaluation_wire_app.php b/tests/Common/FeatureFlags/flag_evaluation_wire_app.php index c1d9b7d77f..baf4fd6ff8 100644 --- a/tests/Common/FeatureFlags/flag_evaluation_wire_app.php +++ b/tests/Common/FeatureFlags/flag_evaluation_wire_app.php @@ -11,7 +11,8 @@ 'observeFullEvaluationData' => true, 'flags' => array(), ); -foreach (array('consented', 'protected', 'coerced', 'empty', 'missing', 'malformed', 'hook-after-error') as $key) { +foreach (array('consented', 'protected', 'coerced', 'empty', 'missing', 'malformed', 'hook-after-error', + 'oversized-identity', 'oversized-successor') as $key) { $config['flags'][$key] = array( 'key' => $key, 'enabled' => true, 'variationType' => 'STRING', 'variations' => array('blue' => array('key' => 'blue', 'value' => 'blue')), @@ -37,6 +38,22 @@ throw new RuntimeException('assignment failed'); } } +// Exercise the public API and native bridge in one request, before any +// explicit flush or reconnect can hide damage to the submitting connection. +// This is deliberately above the native IPC budget, not an exact boundary test. +foreach (array('oversized-identity' => 'ffe-oversized-identity-canary-' . str_repeat('x', 5 * 1024 * 1024), + 'oversized-successor' => 'normal-successor') as $flag => $targetingKey) { + $attributes = array('email' => $flag . '-context-canary@example.test'); + $evaluationContext = array('targetingKey' => $targetingKey, 'attributes' => $attributes); + if (getenv('PHP_FFE_WIRE_OPENFEATURE') === '1') { + $evaluationContext = new \OpenFeature\implementation\flags\EvaluationContext($targetingKey, + new \OpenFeature\implementation\flags\Attributes($attributes)); + } + if ($client->getStringValue($flag, 'fallback', $evaluationContext) !== 'blue') { + throw new RuntimeException('oversized identity or its successor changed assignment'); + } +} +unset($targetingKey, $evaluationContext); $config['observeFullEvaluationData'] = false; \DDTrace\Testing\ffe_load_config(json_encode($config)); $protectedKey = 'ffe-protected-pii-canary@example.test'; diff --git a/tests/OpenFeature/flag_evaluation_openfeature_wire.phpt b/tests/OpenFeature/flag_evaluation_openfeature_wire.phpt index 042390095d..2b9f17a695 100644 --- a/tests/OpenFeature/flag_evaluation_openfeature_wire.phpt +++ b/tests/OpenFeature/flag_evaluation_openfeature_wire.phpt @@ -37,6 +37,8 @@ protected_count=int(1) protected_subject=string(71) "sha256_2234a4963a43ffe952df4e09b1fd0d36f8b49216e5cba4182ae4d01e67cf112a" protected_context_absent=bool(true) protected_raw_bytes_absent=bool(true) +oversized_identity_omits_identity_and_context=bool(true) +oversized_identity_successor_retains_context=bool(true) evaluation_times_preserved=bool(true) identity_omissions_preserve_evaluations=bool(true) first_256_inspected=bool(true) diff --git a/tests/api/Unit/FeatureFlags/flag_evaluation_wire.phpt b/tests/api/Unit/FeatureFlags/flag_evaluation_wire.phpt index 264b0b8682..354ade95e2 100644 --- a/tests/api/Unit/FeatureFlags/flag_evaluation_wire.phpt +++ b/tests/api/Unit/FeatureFlags/flag_evaluation_wire.phpt @@ -35,6 +35,8 @@ protected_count=int(1) protected_subject=string(71) "sha256_2234a4963a43ffe952df4e09b1fd0d36f8b49216e5cba4182ae4d01e67cf112a" protected_context_absent=bool(true) protected_raw_bytes_absent=bool(true) +oversized_identity_omits_identity_and_context=bool(true) +oversized_identity_successor_retains_context=bool(true) evaluation_times_preserved=bool(true) identity_omissions_preserve_evaluations=bool(true) first_256_inspected=bool(true)