From 9328a526255148833adac57da594bf2059b4982e Mon Sep 17 00:00:00 2001 From: Leo Romanovsky Date: Tue, 12 May 2026 12:32:49 -0400 Subject: [PATCH 1/6] Use canonical FFE fixtures --- .github/dependabot.yml | 5 + .gitmodules | 3 + .../OpenFeatureProviderSmokeTest.groovy | 10 +- .../src/test/resources/config/flags-v1.json | 2953 ----------------- .../test-case-boolean-one-of-matches.json | 240 -- .../test-case-comparator-operator-flag.json | 82 - .../data/test-case-disabled-flag.json | 40 - .../resources/data/test-case-empty-flag.json | 40 - .../test-case-flag-with-empty-string.json | 36 - .../data/test-case-integer-flag.json | 382 --- .../data/test-case-kill-switch-flag.json | 434 --- .../data/test-case-microsecond-date-flag.json | 54 - .../test-case-new-user-onboarding-flag.json | 420 --- .../data/test-case-no-allocations-flag.json | 52 - .../data/test-case-null-operator-flag.json | 94 - .../data/test-case-numeric-flag.json | 58 - .../data/test-case-numeric-one-of.json | 122 - .../data/test-case-race-conditions.json | 10 - .../resources/data/test-case-regex-flag.json | 65 - .../test-case-start-and-end-date-flag.json | 58 - .../data/test-flag-that-does-not-exist.json | 40 - .../resources/data/test-json-config-flag.json | 96 - .../data/test-no-allocations-flag.json | 52 - .../data/test-special-characters.json | 78 - .../test-string-with-special-characters.json | 1190 ------- .../src/test/resources/ffe-system-test-data | 1 + 26 files changed, 16 insertions(+), 6599 deletions(-) delete mode 100644 dd-smoke-tests/openfeature/src/test/resources/config/flags-v1.json delete mode 100644 dd-smoke-tests/openfeature/src/test/resources/data/test-case-boolean-one-of-matches.json delete mode 100644 dd-smoke-tests/openfeature/src/test/resources/data/test-case-comparator-operator-flag.json delete mode 100644 dd-smoke-tests/openfeature/src/test/resources/data/test-case-disabled-flag.json delete mode 100644 dd-smoke-tests/openfeature/src/test/resources/data/test-case-empty-flag.json delete mode 100644 dd-smoke-tests/openfeature/src/test/resources/data/test-case-flag-with-empty-string.json delete mode 100644 dd-smoke-tests/openfeature/src/test/resources/data/test-case-integer-flag.json delete mode 100644 dd-smoke-tests/openfeature/src/test/resources/data/test-case-kill-switch-flag.json delete mode 100644 dd-smoke-tests/openfeature/src/test/resources/data/test-case-microsecond-date-flag.json delete mode 100644 dd-smoke-tests/openfeature/src/test/resources/data/test-case-new-user-onboarding-flag.json delete mode 100644 dd-smoke-tests/openfeature/src/test/resources/data/test-case-no-allocations-flag.json delete mode 100644 dd-smoke-tests/openfeature/src/test/resources/data/test-case-null-operator-flag.json delete mode 100644 dd-smoke-tests/openfeature/src/test/resources/data/test-case-numeric-flag.json delete mode 100644 dd-smoke-tests/openfeature/src/test/resources/data/test-case-numeric-one-of.json delete mode 100644 dd-smoke-tests/openfeature/src/test/resources/data/test-case-race-conditions.json delete mode 100644 dd-smoke-tests/openfeature/src/test/resources/data/test-case-regex-flag.json delete mode 100644 dd-smoke-tests/openfeature/src/test/resources/data/test-case-start-and-end-date-flag.json delete mode 100644 dd-smoke-tests/openfeature/src/test/resources/data/test-flag-that-does-not-exist.json delete mode 100644 dd-smoke-tests/openfeature/src/test/resources/data/test-json-config-flag.json delete mode 100644 dd-smoke-tests/openfeature/src/test/resources/data/test-no-allocations-flag.json delete mode 100644 dd-smoke-tests/openfeature/src/test/resources/data/test-special-characters.json delete mode 100644 dd-smoke-tests/openfeature/src/test/resources/data/test-string-with-special-characters.json create mode 160000 dd-smoke-tests/openfeature/src/test/resources/ffe-system-test-data diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 143febaaeb0..1fe9f4cde20 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -36,3 +36,8 @@ updates: prefix: 'chore(build): ' cooldown: default-days: 2 + + - package-ecosystem: gitsubmodule + directory: / + schedule: + interval: weekly diff --git a/.gitmodules b/.gitmodules index 27fc232a993..18769cc41ae 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "dd-java-agent/agent-jmxfetch/integrations-core"] path = dd-java-agent/agent-jmxfetch/integrations-core url = https://github.com/DataDog/integrations-core.git +[submodule "dd-smoke-tests/openfeature/src/test/resources/ffe-system-test-data"] + path = dd-smoke-tests/openfeature/src/test/resources/ffe-system-test-data + url = https://github.com/DataDog/ffe-system-test-data.git diff --git a/dd-smoke-tests/openfeature/src/test/groovy/datadog/smoketest/springboot/OpenFeatureProviderSmokeTest.groovy b/dd-smoke-tests/openfeature/src/test/groovy/datadog/smoketest/springboot/OpenFeatureProviderSmokeTest.groovy index 656bbf4b77e..6c5d5f29e1a 100644 --- a/dd-smoke-tests/openfeature/src/test/groovy/datadog/smoketest/springboot/OpenFeatureProviderSmokeTest.groovy +++ b/dd-smoke-tests/openfeature/src/test/groovy/datadog/smoketest/springboot/OpenFeatureProviderSmokeTest.groovy @@ -8,6 +8,7 @@ import groovy.json.JsonOutput import groovy.json.JsonSlurper import java.nio.file.Files import java.nio.file.Paths +import java.util.Comparator import okhttp3.MediaType import okhttp3.Request import okhttp3.RequestBody @@ -21,8 +22,8 @@ import spock.util.concurrent.PollingConditions class OpenFeatureProviderSmokeTest extends AbstractServerSmokeTest { @Shared - private final rcPayload = new JsonSlurper().parse(fetchResource("config/flags-v1.json")).with { json -> - return JsonOutput.toJson(json.data.attributes) + private final rcPayload = new JsonSlurper().parse(fetchResource("ffe-system-test-data/ufc-config.json")).with { json -> + return JsonOutput.toJson(json) } @Override @@ -116,6 +117,7 @@ class OpenFeatureProviderSmokeTest extends AbstractServerSmokeTest { final responseBody = new JsonSlurper().parse(response.body().byteStream()) responseBody.value == testCase.result.value responseBody.variant == testCase.result.variant + responseBody.reason == testCase.result.reason responseBody.flagMetadata?.allocationKey == testCase.result.flagMetadata?.allocationKey where: @@ -127,11 +129,12 @@ class OpenFeatureProviderSmokeTest extends AbstractServerSmokeTest { } private static List> parseTestCases() { - final folder = fetchResource('data') + final folder = fetchResource('ffe-system-test-data/evaluation-cases') final uri = folder.toURI() final testsPath = Paths.get(uri) final files = Files.list(testsPath) .filter(path -> path.toString().endsWith('.json')) + .sorted(Comparator.comparing(path -> path.fileName.toString())) final result = [] final slurper = new JsonSlurper() files.each { @@ -144,6 +147,7 @@ class OpenFeatureProviderSmokeTest extends AbstractServerSmokeTest { } result.addAll(testCases) } + assert !result.isEmpty() return result } diff --git a/dd-smoke-tests/openfeature/src/test/resources/config/flags-v1.json b/dd-smoke-tests/openfeature/src/test/resources/config/flags-v1.json deleted file mode 100644 index 5b21a9f3661..00000000000 --- a/dd-smoke-tests/openfeature/src/test/resources/config/flags-v1.json +++ /dev/null @@ -1,2953 +0,0 @@ -{ - "data": { - "type": "universal-flag-configuration", - "id": "1", - "attributes": { - "createdAt": "2024-04-17T19:40:53.716Z", - "format": "SERVER", - "environment": { - "name": "Test" - }, - "flags": { - "empty_flag": { - "key": "empty_flag", - "enabled": true, - "variationType": "STRING", - "variations": {}, - "allocations": [] - }, - "disabled_flag": { - "key": "disabled_flag", - "enabled": false, - "variationType": "INTEGER", - "variations": {}, - "allocations": [] - }, - "no_allocations_flag": { - "key": "no_allocations_flag", - "enabled": true, - "variationType": "JSON", - "variations": { - "control": { - "key": "control", - "value": { "variant": "control" } - }, - "treatment": { - "key": "treatment", - "value": { "variant": "treatment" } - } - }, - "allocations": [] - }, - "numeric_flag": { - "key": "numeric_flag", - "enabled": true, - "variationType": "NUMERIC", - "variations": { - "e": { - "key": "e", - "value": 2.7182818 - }, - "pi": { - "key": "pi", - "value": 3.1415926 - } - }, - "allocations": [ - { - "key": "rollout", - "splits": [ - { - "variationKey": "pi", - "shards": [] - } - ], - "doLog": true - } - ] - }, - "regex-flag": { - "key": "regex-flag", - "enabled": true, - "variationType": "STRING", - "variations": { - "partial-example": { - "key": "partial-example", - "value": "partial-example" - }, - "test": { - "key": "test", - "value": "test" - } - }, - "allocations": [ - { - "key": "partial-example", - "rules": [ - { - "conditions": [ - { - "attribute": "email", - "operator": "MATCHES", - "value": "@example\\.com" - } - ] - } - ], - "splits": [ - { - "variationKey": "partial-example", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "test", - "rules": [ - { - "conditions": [ - { - "attribute": "email", - "operator": "MATCHES", - "value": ".*@test\\.com" - } - ] - } - ], - "splits": [ - { - "variationKey": "test", - "shards": [] - } - ], - "doLog": true - } - ] - }, - "numeric-one-of": { - "key": "numeric-one-of", - "enabled": true, - "variationType": "INTEGER", - "variations": { - "1": { - "key": "1", - "value": 1 - }, - "2": { - "key": "2", - "value": 2 - }, - "3": { - "key": "3", - "value": 3 - } - }, - "allocations": [ - { - "key": "1-for-1", - "rules": [ - { - "conditions": [ - { - "attribute": "number", - "operator": "ONE_OF", - "value": ["1"] - } - ] - } - ], - "splits": [ - { - "variationKey": "1", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "2-for-123456789", - "rules": [ - { - "conditions": [ - { - "attribute": "number", - "operator": "ONE_OF", - "value": ["123456789"] - } - ] - } - ], - "splits": [ - { - "variationKey": "2", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "3-for-not-2", - "rules": [ - { - "conditions": [ - { - "attribute": "number", - "operator": "NOT_ONE_OF", - "value": ["2"] - } - ] - } - ], - "splits": [ - { - "variationKey": "3", - "shards": [] - } - ], - "doLog": true - } - ] - }, - "boolean-one-of-matches": { - "key": "boolean-one-of-matches", - "enabled": true, - "variationType": "INTEGER", - "variations": { - "1": { - "key": "1", - "value": 1 - }, - "2": { - "key": "2", - "value": 2 - }, - "3": { - "key": "3", - "value": 3 - }, - "4": { - "key": "4", - "value": 4 - }, - "5": { - "key": "5", - "value": 5 - } - }, - "allocations": [ - { - "key": "1-for-one-of", - "rules": [ - { - "conditions": [ - { - "attribute": "one_of_flag", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "1", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "2-for-matches", - "rules": [ - { - "conditions": [ - { - "attribute": "matches_flag", - "operator": "MATCHES", - "value": "true" - } - ] - } - ], - "splits": [ - { - "variationKey": "2", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "3-for-not-one-of", - "rules": [ - { - "conditions": [ - { - "attribute": "not_one_of_flag", - "operator": "NOT_ONE_OF", - "value": ["false"] - } - ] - } - ], - "splits": [ - { - "variationKey": "3", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "4-for-not-matches", - "rules": [ - { - "conditions": [ - { - "attribute": "not_matches_flag", - "operator": "NOT_MATCHES", - "value": "false" - } - ] - } - ], - "splits": [ - { - "variationKey": "4", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "5-for-matches-null", - "rules": [ - { - "conditions": [ - { - "attribute": "null_flag", - "operator": "ONE_OF", - "value": ["null"] - } - ] - } - ], - "splits": [ - { - "variationKey": "5", - "shards": [] - } - ], - "doLog": true - } - ] - }, - "empty_string_flag": { - "key": "empty_string_flag", - "enabled": true, - "comment": "Testing the empty string as a variation value", - "variationType": "STRING", - "variations": { - "empty_string": { - "key": "empty_string", - "value": "" - }, - "non_empty": { - "key": "non_empty", - "value": "non_empty" - } - }, - "allocations": [ - { - "key": "allocation-empty", - "rules": [ - { - "conditions": [ - { - "attribute": "country", - "operator": "MATCHES", - "value": "US" - } - ] - } - ], - "splits": [ - { - "variationKey": "empty_string", - "shards": [ - { - "salt": "allocation-empty-shards", - "totalShards": 10000, - "ranges": [ - { - "start": 0, - "end": 10000 - } - ] - } - ] - } - ], - "doLog": true - }, - { - "key": "allocation-test", - "rules": [], - "splits": [ - { - "variationKey": "non_empty", - "shards": [ - { - "salt": "allocation-empty-shards", - "totalShards": 10000, - "ranges": [ - { - "start": 0, - "end": 10000 - } - ] - } - ] - } - ], - "doLog": true - } - ] - }, - "kill-switch": { - "key": "kill-switch", - "enabled": true, - "variationType": "BOOLEAN", - "variations": { - "on": { - "key": "on", - "value": true - }, - "off": { - "key": "off", - "value": false - } - }, - "allocations": [ - { - "key": "on-for-NA", - "rules": [ - { - "conditions": [ - { - "attribute": "country", - "operator": "ONE_OF", - "value": ["US", "Canada", "Mexico"] - } - ] - } - ], - "splits": [ - { - "variationKey": "on", - "shards": [ - { - "salt": "some-salt", - "totalShards": 10000, - "ranges": [ - { - "start": 0, - "end": 10000 - } - ] - } - ] - } - ], - "doLog": true - }, - { - "key": "on-for-age-50+", - "rules": [ - { - "conditions": [ - { - "attribute": "age", - "operator": "GTE", - "value": 50 - } - ] - } - ], - "splits": [ - { - "variationKey": "on", - "shards": [ - { - "salt": "some-salt", - "totalShards": 10000, - "ranges": [ - { - "start": 0, - "end": 10000 - } - ] - } - ] - } - ], - "doLog": true - }, - { - "key": "off-for-all", - "rules": [], - "splits": [ - { - "variationKey": "off", - "shards": [] - } - ], - "doLog": true - } - ] - }, - "comparator-operator-test": { - "key": "comparator-operator-test", - "enabled": true, - "variationType": "STRING", - "variations": { - "small": { - "key": "small", - "value": "small" - }, - "medium": { - "key": "medium", - "value": "medium" - }, - "large": { - "key": "large", - "value": "large" - } - }, - "allocations": [ - { - "key": "small-size", - "rules": [ - { - "conditions": [ - { - "attribute": "size", - "operator": "LT", - "value": 10 - } - ] - } - ], - "splits": [ - { - "variationKey": "small", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "medum-size", - "rules": [ - { - "conditions": [ - { - "attribute": "size", - "operator": "GTE", - "value": 10 - }, - { - "attribute": "size", - "operator": "LTE", - "value": 20 - } - ] - } - ], - "splits": [ - { - "variationKey": "medium", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "large-size", - "rules": [ - { - "conditions": [ - { - "attribute": "size", - "operator": "GT", - "value": 25 - } - ] - } - ], - "splits": [ - { - "variationKey": "large", - "shards": [] - } - ], - "doLog": true - } - ] - }, - "start-and-end-date-test": { - "key": "start-and-end-date-test", - "enabled": true, - "variationType": "STRING", - "variations": { - "old": { - "key": "old", - "value": "old" - }, - "current": { - "key": "current", - "value": "current" - }, - "new": { - "key": "new", - "value": "new" - } - }, - "allocations": [ - { - "key": "old-versions", - "splits": [ - { - "variationKey": "old", - "shards": [] - } - ], - "endAt": "2002-10-31T09:00:00.594Z", - "doLog": true - }, - { - "key": "future-versions", - "splits": [ - { - "variationKey": "new", - "shards": [] - } - ], - "startAt": "2052-10-31T09:00:00.594Z", - "doLog": true - }, - { - "key": "current-versions", - "splits": [ - { - "variationKey": "current", - "shards": [] - } - ], - "startAt": "2022-10-31T09:00:00.594Z", - "endAt": "2050-10-31T09:00:00.594Z", - "doLog": true - } - ] - }, - "null-operator-test": { - "key": "null-operator-test", - "enabled": true, - "variationType": "STRING", - "variations": { - "old": { - "key": "old", - "value": "old" - }, - "new": { - "key": "new", - "value": "new" - } - }, - "allocations": [ - { - "key": "null-operator", - "rules": [ - { - "conditions": [ - { - "attribute": "size", - "operator": "IS_NULL", - "value": true - } - ] - }, - { - "conditions": [ - { - "attribute": "size", - "operator": "LT", - "value": 10 - } - ] - } - ], - "splits": [ - { - "variationKey": "old", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "not-null-operator", - "rules": [ - { - "conditions": [ - { - "attribute": "size", - "operator": "IS_NULL", - "value": false - } - ] - } - ], - "splits": [ - { - "variationKey": "new", - "shards": [] - } - ], - "doLog": true - } - ] - }, - "new-user-onboarding": { - "key": "new-user-onboarding", - "enabled": true, - "variationType": "STRING", - "variations": { - "control": { - "key": "control", - "value": "control" - }, - "red": { - "key": "red", - "value": "red" - }, - "blue": { - "key": "blue", - "value": "blue" - }, - "green": { - "key": "green", - "value": "green" - }, - "yellow": { - "key": "yellow", - "value": "yellow" - }, - "purple": { - "key": "purple", - "value": "purple" - } - }, - "allocations": [ - { - "key": "id rule", - "rules": [ - { - "conditions": [ - { - "attribute": "id", - "operator": "MATCHES", - "value": "zach" - } - ] - } - ], - "splits": [ - { - "variationKey": "purple", - "shards": [] - } - ], - "doLog": false - }, - { - "key": "internal users", - "rules": [ - { - "conditions": [ - { - "attribute": "email", - "operator": "MATCHES", - "value": "@mycompany.com" - } - ] - } - ], - "splits": [ - { - "variationKey": "green", - "shards": [] - } - ], - "doLog": false - }, - { - "key": "experiment", - "rules": [ - { - "conditions": [ - { - "attribute": "country", - "operator": "NOT_ONE_OF", - "value": ["US", "Canada", "Mexico"] - } - ] - } - ], - "splits": [ - { - "variationKey": "control", - "shards": [ - { - "salt": "traffic-new-user-onboarding-experiment", - "totalShards": 10000, - "ranges": [ - { - "start": 0, - "end": 6000 - } - ] - }, - { - "salt": "split-new-user-onboarding-experiment", - "totalShards": 10000, - "ranges": [ - { - "start": 0, - "end": 5000 - } - ] - } - ] - }, - { - "variationKey": "red", - "shards": [ - { - "salt": "traffic-new-user-onboarding-experiment", - "totalShards": 10000, - "ranges": [ - { - "start": 0, - "end": 6000 - } - ] - }, - { - "salt": "split-new-user-onboarding-experiment", - "totalShards": 10000, - "ranges": [ - { - "start": 5000, - "end": 8000 - } - ] - } - ] - }, - { - "variationKey": "yellow", - "shards": [ - { - "salt": "traffic-new-user-onboarding-experiment", - "totalShards": 10000, - "ranges": [ - { - "start": 0, - "end": 6000 - } - ] - }, - { - "salt": "split-new-user-onboarding-experiment", - "totalShards": 10000, - "ranges": [ - { - "start": 8000, - "end": 10000 - } - ] - } - ] - } - ], - "doLog": true - }, - { - "key": "rollout", - "rules": [ - { - "conditions": [ - { - "attribute": "country", - "operator": "ONE_OF", - "value": ["US", "Canada", "Mexico"] - } - ] - } - ], - "splits": [ - { - "variationKey": "blue", - "shards": [ - { - "salt": "split-new-user-onboarding-rollout", - "totalShards": 10000, - "ranges": [ - { - "start": 0, - "end": 8000 - } - ] - } - ], - "extraLogging": { - "allocationvalue_type": "rollout", - "owner": "hippo" - } - } - ], - "doLog": true - } - ] - }, - "integer-flag": { - "key": "integer-flag", - "enabled": true, - "variationType": "INTEGER", - "variations": { - "one": { - "key": "one", - "value": 1 - }, - "two": { - "key": "two", - "value": 2 - }, - "three": { - "key": "three", - "value": 3 - } - }, - "allocations": [ - { - "key": "targeted allocation", - "rules": [ - { - "conditions": [ - { - "attribute": "country", - "operator": "ONE_OF", - "value": ["US", "Canada", "Mexico"] - } - ] - }, - { - "conditions": [ - { - "attribute": "email", - "operator": "MATCHES", - "value": ".*@example.com" - } - ] - } - ], - "splits": [ - { - "variationKey": "three", - "shards": [ - { - "salt": "full-range-salt", - "totalShards": 10000, - "ranges": [ - { - "start": 0, - "end": 10000 - } - ] - } - ] - } - ], - "doLog": true - }, - { - "key": "50/50 split", - "rules": [], - "splits": [ - { - "variationKey": "one", - "shards": [ - { - "salt": "split-numeric-flag-some-allocation", - "totalShards": 10000, - "ranges": [ - { - "start": 0, - "end": 5000 - } - ] - } - ] - }, - { - "variationKey": "two", - "shards": [ - { - "salt": "split-numeric-flag-some-allocation", - "totalShards": 10000, - "ranges": [ - { - "start": 5000, - "end": 10000 - } - ] - } - ] - } - ], - "doLog": true - } - ] - }, - "json-config-flag": { - "key": "json-config-flag", - "enabled": true, - "variationType": "JSON", - "variations": { - "one": { - "key": "one", - "value": { "integer": 1, "string": "one", "float": 1.0 } - }, - "two": { - "key": "two", - "value": { "integer": 2, "string": "two", "float": 2.0 } - }, - "empty": { - "key": "empty", - "value": {} - } - }, - "allocations": [ - { - "key": "Optionally Force Empty", - "rules": [ - { - "conditions": [ - { - "attribute": "Force Empty", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "empty", - "shards": [ - { - "salt": "full-range-salt", - "totalShards": 10000, - "ranges": [ - { - "start": 0, - "end": 10000 - } - ] - } - ] - } - ], - "doLog": true - }, - { - "key": "50/50 split", - "rules": [], - "splits": [ - { - "variationKey": "one", - "shards": [ - { - "salt": "traffic-json-flag", - "totalShards": 10000, - "ranges": [ - { - "start": 0, - "end": 10000 - } - ] - }, - { - "salt": "split-json-flag", - "totalShards": 10000, - "ranges": [ - { - "start": 0, - "end": 5000 - } - ] - } - ] - }, - { - "variationKey": "two", - "shards": [ - { - "salt": "traffic-json-flag", - "totalShards": 10000, - "ranges": [ - { - "start": 0, - "end": 10000 - } - ] - }, - { - "salt": "split-json-flag", - "totalShards": 10000, - "ranges": [ - { - "start": 5000, - "end": 10000 - } - ] - } - ] - } - ], - "doLog": true - } - ] - }, - "special-characters": { - "key": "special-characters", - "enabled": true, - "variationType": "JSON", - "variations": { - "de": { - "key": "de", - "value": { "a": "kümmert", "b": "schön" } - }, - "ua": { - "key": "ua", - "value": { "a": "піклуватися", "b": "любов" } - }, - "zh": { - "key": "zh", - "value": { "a": "照顾", "b": "漂亮" } - }, - "emoji": { - "key": "emoji", - "value": { "a": "🤗", "b": "🌸" } - } - }, - "allocations": [ - { - "key": "allocation-test", - "splits": [ - { - "variationKey": "de", - "shards": [ - { - "salt": "split-json-flag", - "totalShards": 10000, - "ranges": [ - { - "start": 0, - "end": 2500 - } - ] - } - ] - }, - { - "variationKey": "ua", - "shards": [ - { - "salt": "split-json-flag", - "totalShards": 10000, - "ranges": [ - { - "start": 2500, - "end": 5000 - } - ] - } - ] - }, - { - "variationKey": "zh", - "shards": [ - { - "salt": "split-json-flag", - "totalShards": 10000, - "ranges": [ - { - "start": 5000, - "end": 7500 - } - ] - } - ] - }, - { - "variationKey": "emoji", - "shards": [ - { - "salt": "split-json-flag", - "totalShards": 10000, - "ranges": [ - { - "start": 7500, - "end": 10000 - } - ] - } - ] - } - ], - "doLog": true - }, - { - "key": "allocation-default", - "splits": [ - { - "variationKey": "de", - "shards": [] - } - ], - "doLog": false - } - ] - }, - "string_flag_with_special_characters": { - "key": "string_flag_with_special_characters", - "enabled": true, - "comment": "Testing the string with special characters and spaces", - "variationType": "STRING", - "variations": { - "string_with_spaces": { - "key": "string_with_spaces", - "value": " a b c d e f " - }, - "string_with_only_one_space": { - "key": "string_with_only_one_space", - "value": " " - }, - "string_with_only_multiple_spaces": { - "key": "string_with_only_multiple_spaces", - "value": " " - }, - "string_with_dots": { - "key": "string_with_dots", - "value": ".a.b.c.d.e.f." - }, - "string_with_only_one_dot": { - "key": "string_with_only_one_dot", - "value": "." - }, - "string_with_only_multiple_dots": { - "key": "string_with_only_multiple_dots", - "value": "......." - }, - "string_with_comas": { - "key": "string_with_comas", - "value": ",a,b,c,d,e,f," - }, - "string_with_only_one_coma": { - "key": "string_with_only_one_coma", - "value": "," - }, - "string_with_only_multiple_comas": { - "key": "string_with_only_multiple_comas", - "value": ",,,,,,," - }, - "string_with_colons": { - "key": "string_with_colons", - "value": ":a:b:c:d:e:f:" - }, - "string_with_only_one_colon": { - "key": "string_with_only_one_colon", - "value": ":" - }, - "string_with_only_multiple_colons": { - "key": "string_with_only_multiple_colons", - "value": ":::::::" - }, - "string_with_semicolons": { - "key": "string_with_semicolons", - "value": ";a;b;c;d;e;f;" - }, - "string_with_only_one_semicolon": { - "key": "string_with_only_one_semicolon", - "value": ";" - }, - "string_with_only_multiple_semicolons": { - "key": "string_with_only_multiple_semicolons", - "value": ";;;;;;;" - }, - "string_with_slashes": { - "key": "string_with_slashes", - "value": "/a/b/c/d/e/f/" - }, - "string_with_only_one_slash": { - "key": "string_with_only_one_slash", - "value": "/" - }, - "string_with_only_multiple_slashes": { - "key": "string_with_only_multiple_slashes", - "value": "///////" - }, - "string_with_dashes": { - "key": "string_with_dashes", - "value": "-a-b-c-d-e-f-" - }, - "string_with_only_one_dash": { - "key": "string_with_only_one_dash", - "value": "-" - }, - "string_with_only_multiple_dashes": { - "key": "string_with_only_multiple_dashes", - "value": "-------" - }, - "string_with_underscores": { - "key": "string_with_underscores", - "value": "_a_b_c_d_e_f_" - }, - "string_with_only_one_underscore": { - "key": "string_with_only_one_underscore", - "value": "_" - }, - "string_with_only_multiple_underscores": { - "key": "string_with_only_multiple_underscores", - "value": "_______" - }, - "string_with_plus_signs": { - "key": "string_with_plus_signs", - "value": "+a+b+c+d+e+f+" - }, - "string_with_only_one_plus_sign": { - "key": "string_with_only_one_plus_sign", - "value": "+" - }, - "string_with_only_multiple_plus_signs": { - "key": "string_with_only_multiple_plus_signs", - "value": "+++++++" - }, - "string_with_equal_signs": { - "key": "string_with_equal_signs", - "value": "=a=b=c=d=e=f=" - }, - "string_with_only_one_equal_sign": { - "key": "string_with_only_one_equal_sign", - "value": "=" - }, - "string_with_only_multiple_equal_signs": { - "key": "string_with_only_multiple_equal_signs", - "value": "=======" - }, - "string_with_dollar_signs": { - "key": "string_with_dollar_signs", - "value": "$a$b$c$d$e$f$" - }, - "string_with_only_one_dollar_sign": { - "key": "string_with_only_one_dollar_sign", - "value": "$" - }, - "string_with_only_multiple_dollar_signs": { - "key": "string_with_only_multiple_dollar_signs", - "value": "$$$$$$$" - }, - "string_with_at_signs": { - "key": "string_with_at_signs", - "value": "@a@b@c@d@e@f@" - }, - "string_with_only_one_at_sign": { - "key": "string_with_only_one_at_sign", - "value": "@" - }, - "string_with_only_multiple_at_signs": { - "key": "string_with_only_multiple_at_signs", - "value": "@@@@@@@" - }, - "string_with_amp_signs": { - "key": "string_with_amp_signs", - "value": "&a&b&c&d&e&f&" - }, - "string_with_only_one_amp_sign": { - "key": "string_with_only_one_amp_sign", - "value": "&" - }, - "string_with_only_multiple_amp_signs": { - "key": "string_with_only_multiple_amp_signs", - "value": "&&&&&&&" - }, - "string_with_hash_signs": { - "key": "string_with_hash_signs", - "value": "#a#b#c#d#e#f#" - }, - "string_with_only_one_hash_sign": { - "key": "string_with_only_one_hash_sign", - "value": "#" - }, - "string_with_only_multiple_hash_signs": { - "key": "string_with_only_multiple_hash_signs", - "value": "#######" - }, - "string_with_percentage_signs": { - "key": "string_with_percentage_signs", - "value": "%a%b%c%d%e%f%" - }, - "string_with_only_one_percentage_sign": { - "key": "string_with_only_one_percentage_sign", - "value": "%" - }, - "string_with_only_multiple_percentage_signs": { - "key": "string_with_only_multiple_percentage_signs", - "value": "%%%%%%%" - }, - "string_with_tilde_signs": { - "key": "string_with_tilde_signs", - "value": "~a~b~c~d~e~f~" - }, - "string_with_only_one_tilde_sign": { - "key": "string_with_only_one_tilde_sign", - "value": "~" - }, - "string_with_only_multiple_tilde_signs": { - "key": "string_with_only_multiple_tilde_signs", - "value": "~~~~~~~" - }, - "string_with_asterix_signs": { - "key": "string_with_asterix_signs", - "value": "*a*b*c*d*e*f*" - }, - "string_with_only_one_asterix_sign": { - "key": "string_with_only_one_asterix_sign", - "value": "*" - }, - "string_with_only_multiple_asterix_signs": { - "key": "string_with_only_multiple_asterix_signs", - "value": "*******" - }, - "string_with_single_quotes": { - "key": "string_with_single_quotes", - "value": "'a'b'c'd'e'f'" - }, - "string_with_only_one_single_quote": { - "key": "string_with_only_one_single_quote", - "value": "'" - }, - "string_with_only_multiple_single_quotes": { - "key": "string_with_only_multiple_single_quotes", - "value": "'''''''" - }, - "string_with_question_marks": { - "key": "string_with_question_marks", - "value": "?a?b?c?d?e?f?" - }, - "string_with_only_one_question_mark": { - "key": "string_with_only_one_question_mark", - "value": "?" - }, - "string_with_only_multiple_question_marks": { - "key": "string_with_only_multiple_question_marks", - "value": "???????" - }, - "string_with_exclamation_marks": { - "key": "string_with_exclamation_marks", - "value": "!a!b!c!d!e!f!" - }, - "string_with_only_one_exclamation_mark": { - "key": "string_with_only_one_exclamation_mark", - "value": "!" - }, - "string_with_only_multiple_exclamation_marks": { - "key": "string_with_only_multiple_exclamation_marks", - "value": "!!!!!!!" - }, - "string_with_opening_parentheses": { - "key": "string_with_opening_parentheses", - "value": "(a(b(c(d(e(f(" - }, - "string_with_only_one_opening_parenthese": { - "key": "string_with_only_one_opening_parenthese", - "value": "(" - }, - "string_with_only_multiple_opening_parentheses": { - "key": "string_with_only_multiple_opening_parentheses", - "value": "(((((((" - }, - "string_with_closing_parentheses": { - "key": "string_with_closing_parentheses", - "value": ")a)b)c)d)e)f)" - }, - "string_with_only_one_closing_parenthese": { - "key": "string_with_only_one_closing_parenthese", - "value": ")" - }, - "string_with_only_multiple_closing_parentheses": { - "key": "string_with_only_multiple_closing_parentheses", - "value": ")))))))" - } - }, - "allocations": [ - { - "key": "allocation-test-string_with_spaces", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_spaces", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_spaces", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_one_space", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_one_space", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_one_space", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_multiple_spaces", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_multiple_spaces", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_multiple_spaces", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_dots", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_dots", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_dots", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_one_dot", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_one_dot", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_one_dot", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_multiple_dots", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_multiple_dots", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_multiple_dots", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_comas", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_comas", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_comas", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_one_coma", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_one_coma", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_one_coma", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_multiple_comas", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_multiple_comas", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_multiple_comas", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_colons", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_colons", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_colons", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_one_colon", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_one_colon", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_one_colon", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_multiple_colons", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_multiple_colons", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_multiple_colons", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_semicolons", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_semicolons", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_semicolons", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_one_semicolon", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_one_semicolon", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_one_semicolon", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_multiple_semicolons", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_multiple_semicolons", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_multiple_semicolons", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_slashes", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_slashes", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_slashes", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_one_slash", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_one_slash", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_one_slash", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_multiple_slashes", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_multiple_slashes", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_multiple_slashes", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_dashes", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_dashes", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_dashes", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_one_dash", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_one_dash", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_one_dash", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_multiple_dashes", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_multiple_dashes", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_multiple_dashes", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_underscores", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_underscores", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_underscores", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_one_underscore", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_one_underscore", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_one_underscore", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_multiple_underscores", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_multiple_underscores", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_multiple_underscores", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_plus_signs", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_plus_signs", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_plus_signs", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_one_plus_sign", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_one_plus_sign", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_one_plus_sign", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_multiple_plus_signs", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_multiple_plus_signs", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_multiple_plus_signs", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_equal_signs", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_equal_signs", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_equal_signs", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_one_equal_sign", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_one_equal_sign", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_one_equal_sign", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_multiple_equal_signs", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_multiple_equal_signs", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_multiple_equal_signs", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_dollar_signs", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_dollar_signs", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_dollar_signs", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_one_dollar_sign", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_one_dollar_sign", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_one_dollar_sign", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_multiple_dollar_signs", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_multiple_dollar_signs", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_multiple_dollar_signs", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_at_signs", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_at_signs", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_at_signs", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_one_at_sign", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_one_at_sign", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_one_at_sign", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_multiple_at_signs", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_multiple_at_signs", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_multiple_at_signs", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_amp_signs", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_amp_signs", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_amp_signs", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_one_amp_sign", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_one_amp_sign", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_one_amp_sign", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_multiple_amp_signs", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_multiple_amp_signs", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_multiple_amp_signs", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_hash_signs", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_hash_signs", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_hash_signs", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_one_hash_sign", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_one_hash_sign", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_one_hash_sign", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_multiple_hash_signs", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_multiple_hash_signs", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_multiple_hash_signs", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_percentage_signs", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_percentage_signs", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_percentage_signs", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_one_percentage_sign", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_one_percentage_sign", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_one_percentage_sign", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_multiple_percentage_signs", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_multiple_percentage_signs", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_multiple_percentage_signs", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_tilde_signs", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_tilde_signs", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_tilde_signs", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_one_tilde_sign", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_one_tilde_sign", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_one_tilde_sign", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_multiple_tilde_signs", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_multiple_tilde_signs", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_multiple_tilde_signs", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_asterix_signs", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_asterix_signs", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_asterix_signs", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_one_asterix_sign", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_one_asterix_sign", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_one_asterix_sign", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_multiple_asterix_signs", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_multiple_asterix_signs", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_multiple_asterix_signs", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_single_quotes", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_single_quotes", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_single_quotes", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_one_single_quote", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_one_single_quote", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_one_single_quote", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_multiple_single_quotes", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_multiple_single_quotes", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_multiple_single_quotes", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_question_marks", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_question_marks", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_question_marks", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_one_question_mark", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_one_question_mark", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_one_question_mark", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_multiple_question_marks", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_multiple_question_marks", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_multiple_question_marks", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_exclamation_marks", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_exclamation_marks", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_exclamation_marks", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_one_exclamation_mark", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_one_exclamation_mark", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_one_exclamation_mark", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_multiple_exclamation_marks", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_multiple_exclamation_marks", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_multiple_exclamation_marks", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_opening_parentheses", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_opening_parentheses", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_opening_parentheses", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_one_opening_parenthese", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_one_opening_parenthese", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_one_opening_parenthese", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_multiple_opening_parentheses", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_multiple_opening_parentheses", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_multiple_opening_parentheses", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_closing_parentheses", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_closing_parentheses", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_closing_parentheses", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_one_closing_parenthese", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_one_closing_parenthese", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_one_closing_parenthese", - "shards": [] - } - ], - "doLog": true - }, - { - "key": "allocation-test-string_with_only_multiple_closing_parentheses", - "rules": [ - { - "conditions": [ - { - "attribute": "string_with_only_multiple_closing_parentheses", - "operator": "ONE_OF", - "value": ["true"] - } - ] - } - ], - "splits": [ - { - "variationKey": "string_with_only_multiple_closing_parentheses", - "shards": [] - } - ], - "doLog": true - } - ] - }, - "microsecond-date-test": { - "key": "microsecond-date-test", - "enabled": true, - "variationType": "STRING", - "variations": { - "expired": { - "key": "expired", - "value": "expired" - }, - "active": { - "key": "active", - "value": "active" - }, - "future": { - "key": "future", - "value": "future" - } - }, - "allocations": [ - { - "key": "expired-allocation", - "splits": [ - { - "variationKey": "expired", - "shards": [] - } - ], - "endAt": "2002-10-31T09:00:00.594321Z", - "doLog": true - }, - { - "key": "future-allocation", - "splits": [ - { - "variationKey": "future", - "shards": [] - } - ], - "startAt": "2052-10-31T09:00:00.123456Z", - "doLog": true - }, - { - "key": "active-allocation", - "splits": [ - { - "variationKey": "active", - "shards": [] - } - ], - "startAt": "2022-10-31T09:00:00.235982Z", - "endAt": "2050-10-31T09:00:00.987654Z", - "doLog": true - } - ] - } - } - } - } -} diff --git a/dd-smoke-tests/openfeature/src/test/resources/data/test-case-boolean-one-of-matches.json b/dd-smoke-tests/openfeature/src/test/resources/data/test-case-boolean-one-of-matches.json deleted file mode 100644 index 6bfbf0effad..00000000000 --- a/dd-smoke-tests/openfeature/src/test/resources/data/test-case-boolean-one-of-matches.json +++ /dev/null @@ -1,240 +0,0 @@ -[ - { - "flag": "boolean-one-of-matches", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "alice", - "attributes": { - "one_of_flag": true - }, - "result": { - "value": 1, - "variant": "1", - "flagMetadata": { - "allocationKey": "1-for-one-of", - "variationType": "number", - "doLog": true - } - } - }, - { - "flag": "boolean-one-of-matches", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "bob", - "attributes": { - "one_of_flag": false - }, - "result": { - "value": 0 - } - }, - { - "flag": "boolean-one-of-matches", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "charlie", - "attributes": { - "one_of_flag": "True" - }, - "result": { - "value": 0 - } - }, - { - "flag": "boolean-one-of-matches", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "derek", - "attributes": { - "matches_flag": true - }, - "result": { - "value": 2, - "variant": "2", - "flagMetadata": { - "allocationKey": "2-for-matches", - "variationType": "number", - "doLog": true - } - } - }, - { - "flag": "boolean-one-of-matches", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "erica", - "attributes": { - "matches_flag": false - }, - "result": { - "value": 0 - } - }, - { - "flag": "boolean-one-of-matches", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "frank", - "attributes": { - "not_matches_flag": false - }, - "result": { - "value": 0 - } - }, - { - "flag": "boolean-one-of-matches", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "george", - "attributes": { - "not_matches_flag": true - }, - "result": { - "value": 4, - "variant": "4", - "flagMetadata": { - "allocationKey": "4-for-not-matches", - "variationType": "number", - "doLog": true - } - } - }, - { - "flag": "boolean-one-of-matches", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "haley", - "attributes": { - "not_matches_flag": "False" - }, - "result": { - "value": 4, - "variant": "4", - "flagMetadata": { - "allocationKey": "4-for-not-matches", - "variationType": "number", - "doLog": true - } - } - }, - { - "flag": "boolean-one-of-matches", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "ivy", - "attributes": { - "not_one_of_flag": true - }, - "result": { - "value": 3, - "variant": "3", - "flagMetadata": { - "allocationKey": "3-for-not-one-of", - "variationType": "number", - "doLog": true - } - } - }, - { - "flag": "boolean-one-of-matches", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "julia", - "attributes": { - "not_one_of_flag": false - }, - "result": { - "value": 0 - } - }, - { - "flag": "boolean-one-of-matches", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "kim", - "attributes": { - "not_one_of_flag": "False" - }, - "result": { - "value": 3, - "variant": "3", - "flagMetadata": { - "allocationKey": "3-for-not-one-of", - "variationType": "number", - "doLog": true - } - } - }, - { - "flag": "boolean-one-of-matches", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "lucas", - "attributes": { - "not_one_of_flag": "true" - }, - "result": { - "value": 3, - "variant": "3", - "flagMetadata": { - "allocationKey": "3-for-not-one-of", - "variationType": "number", - "doLog": true - } - } - }, - { - "flag": "boolean-one-of-matches", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "mike", - "attributes": { - "not_one_of_flag": "false" - }, - "result": { - "value": 0 - } - }, - { - "flag": "boolean-one-of-matches", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "nicole", - "attributes": { - "null_flag": "null" - }, - "result": { - "value": 5, - "variant": "5", - "flagMetadata": { - "allocationKey": "5-for-matches-null", - "variationType": "number", - "doLog": true - } - } - }, - { - "flag": "boolean-one-of-matches", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "owen", - "attributes": { - "null_flag": null - }, - "result": { - "value": 0 - } - }, - { - "flag": "boolean-one-of-matches", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "pete", - "attributes": {}, - "result": { - "value": 0 - } - } -] diff --git a/dd-smoke-tests/openfeature/src/test/resources/data/test-case-comparator-operator-flag.json b/dd-smoke-tests/openfeature/src/test/resources/data/test-case-comparator-operator-flag.json deleted file mode 100644 index a5c8ef07cd4..00000000000 --- a/dd-smoke-tests/openfeature/src/test/resources/data/test-case-comparator-operator-flag.json +++ /dev/null @@ -1,82 +0,0 @@ -[ - { - "flag": "comparator-operator-test", - "variationType": "STRING", - "defaultValue": "unknown", - "targetingKey": "alice", - "attributes": { - "size": 5, - "country": "US" - }, - "result": { - "value": "small", - "variant": "small", - "flagMetadata": { - "allocationKey": "small-size", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "comparator-operator-test", - "variationType": "STRING", - "defaultValue": "unknown", - "targetingKey": "bob", - "attributes": { - "size": 10, - "country": "Canada" - }, - "result": { - "value": "medium", - "variant": "medium", - "flagMetadata": { - "allocationKey": "medum-size", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "comparator-operator-test", - "variationType": "STRING", - "defaultValue": "unknown", - "targetingKey": "charlie", - "attributes": { - "size": 25 - }, - "result": { - "value": "unknown" - } - }, - { - "flag": "comparator-operator-test", - "variationType": "STRING", - "defaultValue": "unknown", - "targetingKey": "david", - "attributes": { - "size": 26 - }, - "result": { - "value": "large", - "variant": "large", - "flagMetadata": { - "allocationKey": "large-size", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "comparator-operator-test", - "variationType": "STRING", - "defaultValue": "unknown", - "targetingKey": "elize", - "attributes": { - "country": "UK" - }, - "result": { - "value": "unknown" - } - } -] diff --git a/dd-smoke-tests/openfeature/src/test/resources/data/test-case-disabled-flag.json b/dd-smoke-tests/openfeature/src/test/resources/data/test-case-disabled-flag.json deleted file mode 100644 index 0da79189ade..00000000000 --- a/dd-smoke-tests/openfeature/src/test/resources/data/test-case-disabled-flag.json +++ /dev/null @@ -1,40 +0,0 @@ -[ - { - "flag": "disabled_flag", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "alice", - "attributes": { - "email": "alice@mycompany.com", - "country": "US" - }, - "result": { - "value": 0 - } - }, - { - "flag": "disabled_flag", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "bob", - "attributes": { - "email": "bob@example.com", - "country": "Canada" - }, - "result": { - "value": 0 - } - }, - { - "flag": "disabled_flag", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "charlie", - "attributes": { - "age": 50 - }, - "result": { - "value": 0 - } - } -] diff --git a/dd-smoke-tests/openfeature/src/test/resources/data/test-case-empty-flag.json b/dd-smoke-tests/openfeature/src/test/resources/data/test-case-empty-flag.json deleted file mode 100644 index 52100b1fe47..00000000000 --- a/dd-smoke-tests/openfeature/src/test/resources/data/test-case-empty-flag.json +++ /dev/null @@ -1,40 +0,0 @@ -[ - { - "flag": "empty_flag", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "alice", - "attributes": { - "email": "alice@mycompany.com", - "country": "US" - }, - "result": { - "value": "default_value" - } - }, - { - "flag": "empty_flag", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "bob", - "attributes": { - "email": "bob@example.com", - "country": "Canada" - }, - "result": { - "value": "default_value" - } - }, - { - "flag": "empty_flag", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "charlie", - "attributes": { - "age": 50 - }, - "result": { - "value": "default_value" - } - } -] diff --git a/dd-smoke-tests/openfeature/src/test/resources/data/test-case-flag-with-empty-string.json b/dd-smoke-tests/openfeature/src/test/resources/data/test-case-flag-with-empty-string.json deleted file mode 100644 index 32a1c1febb7..00000000000 --- a/dd-smoke-tests/openfeature/src/test/resources/data/test-case-flag-with-empty-string.json +++ /dev/null @@ -1,36 +0,0 @@ -[ - { - "flag": "empty_string_flag", - "variationType": "STRING", - "defaultValue": "default", - "targetingKey": "alice", - "attributes": { - "country": "US" - }, - "result": { - "value": "", - "variant": "empty_string", - "flagMetadata": { - "allocationKey": "allocation-empty", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "empty_string_flag", - "variationType": "STRING", - "defaultValue": "default", - "targetingKey": "bob", - "attributes": {}, - "result": { - "value": "non_empty", - "variant": "non_empty", - "flagMetadata": { - "allocationKey": "allocation-test", - "variationType": "string", - "doLog": true - } - } - } -] diff --git a/dd-smoke-tests/openfeature/src/test/resources/data/test-case-integer-flag.json b/dd-smoke-tests/openfeature/src/test/resources/data/test-case-integer-flag.json deleted file mode 100644 index 4a41d042f62..00000000000 --- a/dd-smoke-tests/openfeature/src/test/resources/data/test-case-integer-flag.json +++ /dev/null @@ -1,382 +0,0 @@ -[ - { - "flag": "integer-flag", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "alice", - "attributes": { - "email": "alice@mycompany.com", - "country": "US" - }, - "result": { - "value": 3, - "variant": "three", - "flagMetadata": { - "allocationKey": "targeted allocation", - "variationType": "number", - "doLog": true - } - } - }, - { - "flag": "integer-flag", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "bob", - "attributes": { - "email": "bob@example.com", - "country": "Canada" - }, - "result": { - "value": 3, - "variant": "three", - "flagMetadata": { - "allocationKey": "targeted allocation", - "variationType": "number", - "doLog": true - } - } - }, - { - "flag": "integer-flag", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "charlie", - "attributes": { - "age": 50 - }, - "result": { - "value": 2, - "variant": "two", - "flagMetadata": { - "allocationKey": "50/50 split", - "variationType": "number", - "doLog": true - } - } - }, - { - "flag": "integer-flag", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "debra", - "attributes": { - "email": "test@test.com", - "country": "Mexico", - "age": 25 - }, - "result": { - "value": 3, - "variant": "three", - "flagMetadata": { - "allocationKey": "targeted allocation", - "variationType": "number", - "doLog": true - } - } - }, - { - "flag": "integer-flag", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "1", - "attributes": {}, - "result": { - "value": 2, - "variant": "two", - "flagMetadata": { - "allocationKey": "50/50 split", - "variationType": "number", - "doLog": true - } - } - }, - { - "flag": "integer-flag", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "2", - "attributes": {}, - "result": { - "value": 2, - "variant": "two", - "flagMetadata": { - "allocationKey": "50/50 split", - "variationType": "number", - "doLog": true - } - } - }, - { - "flag": "integer-flag", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "3", - "attributes": {}, - "result": { - "value": 2, - "variant": "two", - "flagMetadata": { - "allocationKey": "50/50 split", - "variationType": "number", - "doLog": true - } - } - }, - { - "flag": "integer-flag", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "4", - "attributes": {}, - "result": { - "value": 2, - "variant": "two", - "flagMetadata": { - "allocationKey": "50/50 split", - "variationType": "number", - "doLog": true - } - } - }, - { - "flag": "integer-flag", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "5", - "attributes": {}, - "result": { - "value": 1, - "variant": "one", - "flagMetadata": { - "allocationKey": "50/50 split", - "variationType": "number", - "doLog": true - } - } - }, - { - "flag": "integer-flag", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "6", - "attributes": {}, - "result": { - "value": 2, - "variant": "two", - "flagMetadata": { - "allocationKey": "50/50 split", - "variationType": "number", - "doLog": true - } - } - }, - { - "flag": "integer-flag", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "7", - "attributes": {}, - "result": { - "value": 1, - "variant": "one", - "flagMetadata": { - "allocationKey": "50/50 split", - "variationType": "number", - "doLog": true - } - } - }, - { - "flag": "integer-flag", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "8", - "attributes": {}, - "result": { - "value": 1, - "variant": "one", - "flagMetadata": { - "allocationKey": "50/50 split", - "variationType": "number", - "doLog": true - } - } - }, - { - "flag": "integer-flag", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "9", - "attributes": {}, - "result": { - "value": 2, - "variant": "two", - "flagMetadata": { - "allocationKey": "50/50 split", - "variationType": "number", - "doLog": true - } - } - }, - { - "flag": "integer-flag", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "10", - "attributes": {}, - "result": { - "value": 2, - "variant": "two", - "flagMetadata": { - "allocationKey": "50/50 split", - "variationType": "number", - "doLog": true - } - } - }, - { - "flag": "integer-flag", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "11", - "attributes": {}, - "result": { - "value": 1, - "variant": "one", - "flagMetadata": { - "allocationKey": "50/50 split", - "variationType": "number", - "doLog": true - } - } - }, - { - "flag": "integer-flag", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "12", - "attributes": {}, - "result": { - "value": 1, - "variant": "one", - "flagMetadata": { - "allocationKey": "50/50 split", - "variationType": "number", - "doLog": true - } - } - }, - { - "flag": "integer-flag", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "13", - "attributes": {}, - "result": { - "value": 2, - "variant": "two", - "flagMetadata": { - "allocationKey": "50/50 split", - "variationType": "number", - "doLog": true - } - } - }, - { - "flag": "integer-flag", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "14", - "attributes": {}, - "result": { - "value": 1, - "variant": "one", - "flagMetadata": { - "allocationKey": "50/50 split", - "variationType": "number", - "doLog": true - } - } - }, - { - "flag": "integer-flag", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "15", - "attributes": {}, - "result": { - "value": 2, - "variant": "two", - "flagMetadata": { - "allocationKey": "50/50 split", - "variationType": "number", - "doLog": true - } - } - }, - { - "flag": "integer-flag", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "16", - "attributes": {}, - "result": { - "value": 2, - "variant": "two", - "flagMetadata": { - "allocationKey": "50/50 split", - "variationType": "number", - "doLog": true - } - } - }, - { - "flag": "integer-flag", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "17", - "attributes": {}, - "result": { - "value": 1, - "variant": "one", - "flagMetadata": { - "allocationKey": "50/50 split", - "variationType": "number", - "doLog": true - } - } - }, - { - "flag": "integer-flag", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "18", - "attributes": {}, - "result": { - "value": 1, - "variant": "one", - "flagMetadata": { - "allocationKey": "50/50 split", - "variationType": "number", - "doLog": true - } - } - }, - { - "flag": "integer-flag", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "19", - "attributes": {}, - "result": { - "value": 1, - "variant": "one", - "flagMetadata": { - "allocationKey": "50/50 split", - "variationType": "number", - "doLog": true - } - } - } -] diff --git a/dd-smoke-tests/openfeature/src/test/resources/data/test-case-kill-switch-flag.json b/dd-smoke-tests/openfeature/src/test/resources/data/test-case-kill-switch-flag.json deleted file mode 100644 index 29e65ba5bb4..00000000000 --- a/dd-smoke-tests/openfeature/src/test/resources/data/test-case-kill-switch-flag.json +++ /dev/null @@ -1,434 +0,0 @@ -[ - { - "flag": "kill-switch", - "variationType": "BOOLEAN", - "defaultValue": false, - "targetingKey": "alice", - "attributes": { - "email": "alice@mycompany.com", - "country": "US" - }, - "result": { - "value": true, - "variant": "on", - "flagMetadata": { - "allocationKey": "on-for-NA", - "variationType": "boolean", - "doLog": true - } - } - }, - { - "flag": "kill-switch", - "variationType": "BOOLEAN", - "defaultValue": false, - "targetingKey": "bob", - "attributes": { - "email": "bob@example.com", - "country": "Canada" - }, - "result": { - "value": true, - "variant": "on", - "flagMetadata": { - "allocationKey": "on-for-NA", - "variationType": "boolean", - "doLog": true - } - } - }, - { - "flag": "kill-switch", - "variationType": "BOOLEAN", - "defaultValue": false, - "targetingKey": "barbara", - "attributes": { - "email": "barbara@example.com", - "country": "canada" - }, - "result": { - "value": false, - "variant": "off", - "flagMetadata": { - "allocationKey": "off-for-all", - "variationType": "boolean", - "doLog": true - } - } - }, - { - "flag": "kill-switch", - "variationType": "BOOLEAN", - "defaultValue": false, - "targetingKey": "charlie", - "attributes": { - "age": 40 - }, - "result": { - "value": false, - "variant": "off", - "flagMetadata": { - "allocationKey": "off-for-all", - "variationType": "boolean", - "doLog": true - } - } - }, - { - "flag": "kill-switch", - "variationType": "BOOLEAN", - "defaultValue": false, - "targetingKey": "debra", - "attributes": { - "email": "test@test.com", - "country": "Mexico", - "age": 25 - }, - "result": { - "value": true, - "variant": "on", - "flagMetadata": { - "allocationKey": "on-for-NA", - "variationType": "boolean", - "doLog": true - } - } - }, - { - "flag": "kill-switch", - "variationType": "BOOLEAN", - "defaultValue": false, - "targetingKey": "1", - "attributes": {}, - "result": { - "value": false, - "variant": "off", - "flagMetadata": { - "allocationKey": "off-for-all", - "variationType": "boolean", - "doLog": true - } - } - }, - { - "flag": "kill-switch", - "variationType": "BOOLEAN", - "defaultValue": false, - "targetingKey": "2", - "attributes": { - "country": "Mexico" - }, - "result": { - "value": true, - "variant": "on", - "flagMetadata": { - "allocationKey": "on-for-NA", - "variationType": "boolean", - "doLog": true - } - } - }, - { - "flag": "kill-switch", - "variationType": "BOOLEAN", - "defaultValue": false, - "targetingKey": "3", - "attributes": { - "country": "UK", - "age": 50 - }, - "result": { - "value": true, - "variant": "on", - "flagMetadata": { - "allocationKey": "on-for-age-50+", - "variationType": "boolean", - "doLog": true - } - } - }, - { - "flag": "kill-switch", - "variationType": "BOOLEAN", - "defaultValue": false, - "targetingKey": "4", - "attributes": { - "country": "Germany" - }, - "result": { - "value": false, - "variant": "off", - "flagMetadata": { - "allocationKey": "off-for-all", - "variationType": "boolean", - "doLog": true - } - } - }, - { - "flag": "kill-switch", - "variationType": "BOOLEAN", - "defaultValue": false, - "targetingKey": "5", - "attributes": { - "country": "Germany" - }, - "result": { - "value": false, - "variant": "off", - "flagMetadata": { - "allocationKey": "off-for-all", - "variationType": "boolean", - "doLog": true - } - } - }, - { - "flag": "kill-switch", - "variationType": "BOOLEAN", - "defaultValue": false, - "targetingKey": "6", - "attributes": { - "country": "Germany" - }, - "result": { - "value": false, - "variant": "off", - "flagMetadata": { - "allocationKey": "off-for-all", - "variationType": "boolean", - "doLog": true - } - } - }, - { - "flag": "kill-switch", - "variationType": "BOOLEAN", - "defaultValue": false, - "targetingKey": "7", - "attributes": { - "country": "US", - "age": 12 - }, - "result": { - "value": true, - "variant": "on", - "flagMetadata": { - "allocationKey": "on-for-NA", - "variationType": "boolean", - "doLog": true - } - } - }, - { - "flag": "kill-switch", - "variationType": "BOOLEAN", - "defaultValue": false, - "targetingKey": "8", - "attributes": { - "country": "Italy", - "age": 60 - }, - "result": { - "value": true, - "variant": "on", - "flagMetadata": { - "allocationKey": "on-for-age-50+", - "variationType": "boolean", - "doLog": true - } - } - }, - { - "flag": "kill-switch", - "variationType": "BOOLEAN", - "defaultValue": false, - "targetingKey": "9", - "attributes": { - "email": "email@email.com" - }, - "result": { - "value": false, - "variant": "off", - "flagMetadata": { - "allocationKey": "off-for-all", - "variationType": "boolean", - "doLog": true - } - } - }, - { - "flag": "kill-switch", - "variationType": "BOOLEAN", - "defaultValue": false, - "targetingKey": "10", - "attributes": {}, - "result": { - "value": false, - "variant": "off", - "flagMetadata": { - "allocationKey": "off-for-all", - "variationType": "boolean", - "doLog": true - } - } - }, - { - "flag": "kill-switch", - "variationType": "BOOLEAN", - "defaultValue": false, - "targetingKey": "11", - "attributes": {}, - "result": { - "value": false, - "variant": "off", - "flagMetadata": { - "allocationKey": "off-for-all", - "variationType": "boolean", - "doLog": true - } - } - }, - { - "flag": "kill-switch", - "variationType": "BOOLEAN", - "defaultValue": false, - "targetingKey": "12", - "attributes": { - "country": "US" - }, - "result": { - "value": true, - "variant": "on", - "flagMetadata": { - "allocationKey": "on-for-NA", - "variationType": "boolean", - "doLog": true - } - } - }, - { - "flag": "kill-switch", - "variationType": "BOOLEAN", - "defaultValue": false, - "targetingKey": "13", - "attributes": { - "country": "Canada" - }, - "result": { - "value": true, - "variant": "on", - "flagMetadata": { - "allocationKey": "on-for-NA", - "variationType": "boolean", - "doLog": true - } - } - }, - { - "flag": "kill-switch", - "variationType": "BOOLEAN", - "defaultValue": false, - "targetingKey": "14", - "attributes": {}, - "result": { - "value": false, - "variant": "off", - "flagMetadata": { - "allocationKey": "off-for-all", - "variationType": "boolean", - "doLog": true - } - } - }, - { - "flag": "kill-switch", - "variationType": "BOOLEAN", - "defaultValue": false, - "targetingKey": "15", - "attributes": { - "country": "Denmark" - }, - "result": { - "value": false, - "variant": "off", - "flagMetadata": { - "allocationKey": "off-for-all", - "variationType": "boolean", - "doLog": true - } - } - }, - { - "flag": "kill-switch", - "variationType": "BOOLEAN", - "defaultValue": false, - "targetingKey": "16", - "attributes": { - "country": "Norway" - }, - "result": { - "value": false, - "variant": "off", - "flagMetadata": { - "allocationKey": "off-for-all", - "variationType": "boolean", - "doLog": true - } - } - }, - { - "flag": "kill-switch", - "variationType": "BOOLEAN", - "defaultValue": false, - "targetingKey": "17", - "attributes": { - "country": "UK" - }, - "result": { - "value": false, - "variant": "off", - "flagMetadata": { - "allocationKey": "off-for-all", - "variationType": "boolean", - "doLog": true - } - } - }, - { - "flag": "kill-switch", - "variationType": "BOOLEAN", - "defaultValue": false, - "targetingKey": "18", - "attributes": { - "country": "UK" - }, - "result": { - "value": false, - "variant": "off", - "flagMetadata": { - "allocationKey": "off-for-all", - "variationType": "boolean", - "doLog": true - } - } - }, - { - "flag": "kill-switch", - "variationType": "BOOLEAN", - "defaultValue": false, - "targetingKey": "19", - "attributes": { - "country": "UK" - }, - "result": { - "value": false, - "variant": "off", - "flagMetadata": { - "allocationKey": "off-for-all", - "variationType": "boolean", - "doLog": true - } - } - } -] diff --git a/dd-smoke-tests/openfeature/src/test/resources/data/test-case-microsecond-date-flag.json b/dd-smoke-tests/openfeature/src/test/resources/data/test-case-microsecond-date-flag.json deleted file mode 100644 index d363b260c42..00000000000 --- a/dd-smoke-tests/openfeature/src/test/resources/data/test-case-microsecond-date-flag.json +++ /dev/null @@ -1,54 +0,0 @@ -[ - { - "flag": "microsecond-date-test", - "variationType": "STRING", - "defaultValue": "unknown", - "targetingKey": "alice", - "attributes": {}, - "result": { - "value": "active", - "variant": "active", - "flagMetadata": { - "allocationKey": "active-allocation", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "microsecond-date-test", - "variationType": "STRING", - "defaultValue": "unknown", - "targetingKey": "bob", - "attributes": { - "country": "US" - }, - "result": { - "value": "active", - "variant": "active", - "flagMetadata": { - "allocationKey": "active-allocation", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "microsecond-date-test", - "variationType": "STRING", - "defaultValue": "unknown", - "targetingKey": "charlie", - "attributes": { - "version": "1.0.0" - }, - "result": { - "value": "active", - "variant": "active", - "flagMetadata": { - "allocationKey": "active-allocation", - "variationType": "string", - "doLog": true - } - } - } -] diff --git a/dd-smoke-tests/openfeature/src/test/resources/data/test-case-new-user-onboarding-flag.json b/dd-smoke-tests/openfeature/src/test/resources/data/test-case-new-user-onboarding-flag.json deleted file mode 100644 index 3845597270e..00000000000 --- a/dd-smoke-tests/openfeature/src/test/resources/data/test-case-new-user-onboarding-flag.json +++ /dev/null @@ -1,420 +0,0 @@ -[ - { - "flag": "new-user-onboarding", - "variationType": "STRING", - "defaultValue": "default", - "targetingKey": "alice", - "attributes": { - "email": "alice@mycompany.com", - "country": "US" - }, - "result": { - "value": "green", - "variant": "green", - "flagMetadata": { - "allocationKey": "internal users", - "variationType": "string", - "doLog": false - } - } - }, - { - "flag": "new-user-onboarding", - "variationType": "STRING", - "defaultValue": "default", - "targetingKey": "bob", - "attributes": { - "email": "bob@example.com", - "country": "Canada" - }, - "result": { - "value": "default" - } - }, - { - "flag": "new-user-onboarding", - "variationType": "STRING", - "defaultValue": "default", - "targetingKey": "charlie", - "attributes": { - "age": 50 - }, - "result": { - "value": "default" - } - }, - { - "flag": "new-user-onboarding", - "variationType": "STRING", - "defaultValue": "default", - "targetingKey": "debra", - "attributes": { - "email": "test@test.com", - "country": "Mexico", - "age": 25 - }, - "result": { - "value": "blue", - "variant": "blue", - "flagMetadata": { - "allocationKey": "rollout", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "new-user-onboarding", - "variationType": "STRING", - "defaultValue": "default", - "targetingKey": "zach", - "attributes": { - "email": "test@test.com", - "country": "Mexico", - "age": 25 - }, - "result": { - "value": "purple", - "variant": "purple", - "flagMetadata": { - "allocationKey": "id rule", - "variationType": "string", - "doLog": false - } - } - }, - { - "flag": "new-user-onboarding", - "variationType": "STRING", - "defaultValue": "default", - "targetingKey": "zach", - "attributes": { - "id": "override-id", - "email": "test@test.com", - "country": "Mexico", - "age": 25 - }, - "result": { - "value": "blue", - "variant": "blue", - "flagMetadata": { - "allocationKey": "rollout", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "new-user-onboarding", - "variationType": "STRING", - "defaultValue": "default", - "targetingKey": "Zach", - "attributes": { - "email": "test@test.com", - "country": "Mexico", - "age": 25 - }, - "result": { - "value": "default" - } - }, - { - "flag": "new-user-onboarding", - "variationType": "STRING", - "defaultValue": "default", - "targetingKey": "1", - "attributes": {}, - "result": { - "value": "default" - } - }, - { - "flag": "new-user-onboarding", - "variationType": "STRING", - "defaultValue": "default", - "targetingKey": "2", - "attributes": { - "country": "Mexico" - }, - "result": { - "value": "blue", - "variant": "blue", - "flagMetadata": { - "allocationKey": "rollout", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "new-user-onboarding", - "variationType": "STRING", - "defaultValue": "default", - "targetingKey": "3", - "attributes": { - "country": "UK", - "age": 33 - }, - "result": { - "value": "control", - "variant": "control", - "flagMetadata": { - "allocationKey": "experiment", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "new-user-onboarding", - "variationType": "STRING", - "defaultValue": "default", - "targetingKey": "4", - "attributes": { - "country": "Germany" - }, - "result": { - "value": "red", - "variant": "red", - "flagMetadata": { - "allocationKey": "experiment", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "new-user-onboarding", - "variationType": "STRING", - "defaultValue": "default", - "targetingKey": "5", - "attributes": { - "country": "Germany" - }, - "result": { - "value": "yellow", - "variant": "yellow", - "flagMetadata": { - "allocationKey": "experiment", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "new-user-onboarding", - "variationType": "STRING", - "defaultValue": "default", - "targetingKey": "6", - "attributes": { - "country": "Germany" - }, - "result": { - "value": "yellow", - "variant": "yellow", - "flagMetadata": { - "allocationKey": "experiment", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "new-user-onboarding", - "variationType": "STRING", - "defaultValue": "default", - "targetingKey": "7", - "attributes": { - "country": "US" - }, - "result": { - "value": "blue", - "variant": "blue", - "flagMetadata": { - "allocationKey": "rollout", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "new-user-onboarding", - "variationType": "STRING", - "defaultValue": "default", - "targetingKey": "8", - "attributes": { - "country": "Italy" - }, - "result": { - "value": "red", - "variant": "red", - "flagMetadata": { - "allocationKey": "experiment", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "new-user-onboarding", - "variationType": "STRING", - "defaultValue": "default", - "targetingKey": "9", - "attributes": { - "email": "email@email.com" - }, - "result": { - "value": "default" - } - }, - { - "flag": "new-user-onboarding", - "variationType": "STRING", - "defaultValue": "default", - "targetingKey": "10", - "attributes": {}, - "result": { - "value": "default" - } - }, - { - "flag": "new-user-onboarding", - "variationType": "STRING", - "defaultValue": "default", - "targetingKey": "11", - "attributes": {}, - "result": { - "value": "default" - } - }, - { - "flag": "new-user-onboarding", - "variationType": "STRING", - "defaultValue": "default", - "targetingKey": "12", - "attributes": { - "country": "US" - }, - "result": { - "value": "blue", - "variant": "blue", - "flagMetadata": { - "allocationKey": "rollout", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "new-user-onboarding", - "variationType": "STRING", - "defaultValue": "default", - "targetingKey": "13", - "attributes": { - "country": "Canada" - }, - "result": { - "value": "blue", - "variant": "blue", - "flagMetadata": { - "allocationKey": "rollout", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "new-user-onboarding", - "variationType": "STRING", - "defaultValue": "default", - "targetingKey": "14", - "attributes": {}, - "result": { - "value": "default" - } - }, - { - "flag": "new-user-onboarding", - "variationType": "STRING", - "defaultValue": "default", - "targetingKey": "15", - "attributes": { - "country": "Denmark" - }, - "result": { - "value": "yellow", - "variant": "yellow", - "flagMetadata": { - "allocationKey": "experiment", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "new-user-onboarding", - "variationType": "STRING", - "defaultValue": "default", - "targetingKey": "16", - "attributes": { - "country": "Norway" - }, - "result": { - "value": "control", - "variant": "control", - "flagMetadata": { - "allocationKey": "experiment", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "new-user-onboarding", - "variationType": "STRING", - "defaultValue": "default", - "targetingKey": "17", - "attributes": { - "country": "UK" - }, - "result": { - "value": "control", - "variant": "control", - "flagMetadata": { - "allocationKey": "experiment", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "new-user-onboarding", - "variationType": "STRING", - "defaultValue": "default", - "targetingKey": "18", - "attributes": { - "country": "UK" - }, - "result": { - "value": "default" - } - }, - { - "flag": "new-user-onboarding", - "variationType": "STRING", - "defaultValue": "default", - "targetingKey": "19", - "attributes": { - "country": "UK" - }, - "result": { - "value": "red", - "variant": "red", - "flagMetadata": { - "allocationKey": "experiment", - "variationType": "string", - "doLog": true - } - } - } -] diff --git a/dd-smoke-tests/openfeature/src/test/resources/data/test-case-no-allocations-flag.json b/dd-smoke-tests/openfeature/src/test/resources/data/test-case-no-allocations-flag.json deleted file mode 100644 index 132c39db32a..00000000000 --- a/dd-smoke-tests/openfeature/src/test/resources/data/test-case-no-allocations-flag.json +++ /dev/null @@ -1,52 +0,0 @@ -[ - { - "flag": "no_allocations_flag", - "variationType": "JSON", - "defaultValue": { - "hello": "world" - }, - "targetingKey": "alice", - "attributes": { - "email": "alice@mycompany.com", - "country": "US" - }, - "result": { - "value": { - "hello": "world" - } - } - }, - { - "flag": "no_allocations_flag", - "variationType": "JSON", - "defaultValue": { - "hello": "world" - }, - "targetingKey": "bob", - "attributes": { - "email": "bob@example.com", - "country": "Canada" - }, - "result": { - "value": { - "hello": "world" - } - } - }, - { - "flag": "no_allocations_flag", - "variationType": "JSON", - "defaultValue": { - "hello": "world" - }, - "targetingKey": "charlie", - "attributes": { - "age": 50 - }, - "result": { - "value": { - "hello": "world" - } - } - } -] diff --git a/dd-smoke-tests/openfeature/src/test/resources/data/test-case-null-operator-flag.json b/dd-smoke-tests/openfeature/src/test/resources/data/test-case-null-operator-flag.json deleted file mode 100644 index dd5c687b893..00000000000 --- a/dd-smoke-tests/openfeature/src/test/resources/data/test-case-null-operator-flag.json +++ /dev/null @@ -1,94 +0,0 @@ -[ - { - "flag": "null-operator-test", - "variationType": "STRING", - "defaultValue": "default-null", - "targetingKey": "alice", - "attributes": { - "size": 5, - "country": "US" - }, - "result": { - "value": "old", - "variant": "old", - "flagMetadata": { - "allocationKey": "null-operator", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "null-operator-test", - "variationType": "STRING", - "defaultValue": "default-null", - "targetingKey": "bob", - "attributes": { - "size": 10, - "country": "Canada" - }, - "result": { - "value": "new", - "variant": "new", - "flagMetadata": { - "allocationKey": "not-null-operator", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "null-operator-test", - "variationType": "STRING", - "defaultValue": "default-null", - "targetingKey": "charlie", - "attributes": { - "size": null - }, - "result": { - "value": "old", - "variant": "old", - "flagMetadata": { - "allocationKey": "null-operator", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "null-operator-test", - "variationType": "STRING", - "defaultValue": "default-null", - "targetingKey": "david", - "attributes": { - "size": 26 - }, - "result": { - "value": "new", - "variant": "new", - "flagMetadata": { - "allocationKey": "not-null-operator", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "null-operator-test", - "variationType": "STRING", - "defaultValue": "default-null", - "targetingKey": "elize", - "attributes": { - "country": "UK" - }, - "result": { - "value": "old", - "variant": "old", - "flagMetadata": { - "allocationKey": "null-operator", - "variationType": "string", - "doLog": true - } - } - } -] diff --git a/dd-smoke-tests/openfeature/src/test/resources/data/test-case-numeric-flag.json b/dd-smoke-tests/openfeature/src/test/resources/data/test-case-numeric-flag.json deleted file mode 100644 index 0e6ed8b1b3a..00000000000 --- a/dd-smoke-tests/openfeature/src/test/resources/data/test-case-numeric-flag.json +++ /dev/null @@ -1,58 +0,0 @@ -[ - { - "flag": "numeric_flag", - "variationType": "NUMERIC", - "defaultValue": 0.0, - "targetingKey": "alice", - "attributes": { - "email": "alice@mycompany.com", - "country": "US" - }, - "result": { - "value": 3.1415926, - "variant": "pi", - "flagMetadata": { - "allocationKey": "rollout", - "variationType": "number", - "doLog": true - } - } - }, - { - "flag": "numeric_flag", - "variationType": "NUMERIC", - "defaultValue": 0.0, - "targetingKey": "bob", - "attributes": { - "email": "bob@example.com", - "country": "Canada" - }, - "result": { - "value": 3.1415926, - "variant": "pi", - "flagMetadata": { - "allocationKey": "rollout", - "variationType": "number", - "doLog": true - } - } - }, - { - "flag": "numeric_flag", - "variationType": "NUMERIC", - "defaultValue": 0.0, - "targetingKey": "charlie", - "attributes": { - "age": 50 - }, - "result": { - "value": 3.1415926, - "variant": "pi", - "flagMetadata": { - "allocationKey": "rollout", - "variationType": "number", - "doLog": true - } - } - } -] diff --git a/dd-smoke-tests/openfeature/src/test/resources/data/test-case-numeric-one-of.json b/dd-smoke-tests/openfeature/src/test/resources/data/test-case-numeric-one-of.json deleted file mode 100644 index 5ab68af5196..00000000000 --- a/dd-smoke-tests/openfeature/src/test/resources/data/test-case-numeric-one-of.json +++ /dev/null @@ -1,122 +0,0 @@ -[ - { - "flag": "numeric-one-of", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "alice", - "attributes": { - "number": 1 - }, - "result": { - "value": 1, - "variant": "1", - "flagMetadata": { - "allocationKey": "1-for-1", - "variationType": "number", - "doLog": true - } - } - }, - { - "flag": "numeric-one-of", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "bob", - "attributes": { - "number": 2 - }, - "result": { - "value": 0 - } - }, - { - "flag": "numeric-one-of", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "charlie", - "attributes": { - "number": 3 - }, - "result": { - "value": 3, - "variant": "3", - "flagMetadata": { - "allocationKey": "3-for-not-2", - "variationType": "number", - "doLog": true - } - } - }, - { - "flag": "numeric-one-of", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "derek", - "attributes": { - "number": 4 - }, - "result": { - "value": 3, - "variant": "3", - "flagMetadata": { - "allocationKey": "3-for-not-2", - "variationType": "number", - "doLog": true - } - } - }, - { - "flag": "numeric-one-of", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "erica", - "attributes": { - "number": "1" - }, - "result": { - "value": 1, - "variant": "1", - "flagMetadata": { - "allocationKey": "1-for-1", - "variationType": "number", - "doLog": true - } - } - }, - { - "flag": "numeric-one-of", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "frank", - "attributes": { - "number": 1 - }, - "result": { - "value": 1, - "variant": "1", - "flagMetadata": { - "allocationKey": "1-for-1", - "variationType": "number", - "doLog": true - } - } - }, - { - "flag": "numeric-one-of", - "variationType": "INTEGER", - "defaultValue": 0, - "targetingKey": "george", - "attributes": { - "number": 123456789 - }, - "result": { - "value": 2, - "variant": "2", - "flagMetadata": { - "allocationKey": "2-for-123456789", - "variationType": "number", - "doLog": true - } - } - } -] diff --git a/dd-smoke-tests/openfeature/src/test/resources/data/test-case-race-conditions.json b/dd-smoke-tests/openfeature/src/test/resources/data/test-case-race-conditions.json deleted file mode 100644 index fa940c843b4..00000000000 --- a/dd-smoke-tests/openfeature/src/test/resources/data/test-case-race-conditions.json +++ /dev/null @@ -1,10 +0,0 @@ -[ - { - "flag": "numeric-one-of", - "variationType": "INTEGER", - "defaultValue": 0, - "result": { - "value": 0 - } - } -] diff --git a/dd-smoke-tests/openfeature/src/test/resources/data/test-case-regex-flag.json b/dd-smoke-tests/openfeature/src/test/resources/data/test-case-regex-flag.json deleted file mode 100644 index 952a37aabcf..00000000000 --- a/dd-smoke-tests/openfeature/src/test/resources/data/test-case-regex-flag.json +++ /dev/null @@ -1,65 +0,0 @@ -[ - { - "flag": "regex-flag", - "variationType": "STRING", - "defaultValue": "none", - "targetingKey": "alice", - "attributes": { - "version": "1.15.0", - "email": "alice@example.com" - }, - "result": { - "value": "partial-example", - "variant": "partial-example", - "flagMetadata": { - "allocationKey": "partial-example", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "regex-flag", - "variationType": "STRING", - "defaultValue": "none", - "targetingKey": "bob", - "attributes": { - "version": "0.20.1", - "email": "bob@test.com" - }, - "result": { - "value": "test", - "variant": "test", - "flagMetadata": { - "allocationKey": "test", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "regex-flag", - "variationType": "STRING", - "defaultValue": "none", - "targetingKey": "charlie", - "attributes": { - "version": "2.1.13" - }, - "result": { - "value": "none" - } - }, - { - "flag": "regex-flag", - "variationType": "STRING", - "defaultValue": "none", - "targetingKey": "derek", - "attributes": { - "version": "2.1.13", - "email": "derek@gmail.com" - }, - "result": { - "value": "none" - } - } -] diff --git a/dd-smoke-tests/openfeature/src/test/resources/data/test-case-start-and-end-date-flag.json b/dd-smoke-tests/openfeature/src/test/resources/data/test-case-start-and-end-date-flag.json deleted file mode 100644 index caf805d1432..00000000000 --- a/dd-smoke-tests/openfeature/src/test/resources/data/test-case-start-and-end-date-flag.json +++ /dev/null @@ -1,58 +0,0 @@ -[ - { - "flag": "start-and-end-date-test", - "variationType": "STRING", - "defaultValue": "unknown", - "targetingKey": "alice", - "attributes": { - "version": "1.15.0", - "country": "US" - }, - "result": { - "value": "current", - "variant": "current", - "flagMetadata": { - "allocationKey": "current-versions", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "start-and-end-date-test", - "variationType": "STRING", - "defaultValue": "unknown", - "targetingKey": "bob", - "attributes": { - "version": "0.20.1", - "country": "Canada" - }, - "result": { - "value": "current", - "variant": "current", - "flagMetadata": { - "allocationKey": "current-versions", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "start-and-end-date-test", - "variationType": "STRING", - "defaultValue": "unknown", - "targetingKey": "charlie", - "attributes": { - "version": "2.1.13" - }, - "result": { - "value": "current", - "variant": "current", - "flagMetadata": { - "allocationKey": "current-versions", - "variationType": "string", - "doLog": true - } - } - } -] diff --git a/dd-smoke-tests/openfeature/src/test/resources/data/test-flag-that-does-not-exist.json b/dd-smoke-tests/openfeature/src/test/resources/data/test-flag-that-does-not-exist.json deleted file mode 100644 index 7499bba1c50..00000000000 --- a/dd-smoke-tests/openfeature/src/test/resources/data/test-flag-that-does-not-exist.json +++ /dev/null @@ -1,40 +0,0 @@ -[ - { - "flag": "flag-that-does-not-exist", - "variationType": "NUMERIC", - "defaultValue": 0.0, - "targetingKey": "alice", - "attributes": { - "email": "alice@mycompany.com", - "country": "US" - }, - "result": { - "value": 0.0 - } - }, - { - "flag": "flag-that-does-not-exist", - "variationType": "NUMERIC", - "defaultValue": 0.0, - "targetingKey": "bob", - "attributes": { - "email": "bob@example.com", - "country": "Canada" - }, - "result": { - "value": 0.0 - } - }, - { - "flag": "flag-that-does-not-exist", - "variationType": "NUMERIC", - "defaultValue": 0.0, - "targetingKey": "charlie", - "attributes": { - "age": 50 - }, - "result": { - "value": 0.0 - } - } -] diff --git a/dd-smoke-tests/openfeature/src/test/resources/data/test-json-config-flag.json b/dd-smoke-tests/openfeature/src/test/resources/data/test-json-config-flag.json deleted file mode 100644 index 3d4478ff711..00000000000 --- a/dd-smoke-tests/openfeature/src/test/resources/data/test-json-config-flag.json +++ /dev/null @@ -1,96 +0,0 @@ -[ - { - "flag": "json-config-flag", - "variationType": "JSON", - "defaultValue": { - "foo": "bar" - }, - "targetingKey": "alice", - "attributes": { - "email": "alice@mycompany.com", - "country": "US" - }, - "result": { - "value": { - "integer": 1, - "string": "one", - "float": 1.0 - }, - "variant": "one", - "flagMetadata": { - "allocationKey": "50/50 split", - "variationType": "object", - "doLog": true - } - } - }, - { - "flag": "json-config-flag", - "variationType": "JSON", - "defaultValue": { - "foo": "bar" - }, - "targetingKey": "bob", - "attributes": { - "email": "bob@example.com", - "country": "Canada" - }, - "result": { - "value": { - "integer": 2, - "string": "two", - "float": 2.0 - }, - "variant": "two", - "flagMetadata": { - "allocationKey": "50/50 split", - "variationType": "object", - "doLog": true - } - } - }, - { - "flag": "json-config-flag", - "variationType": "JSON", - "defaultValue": { - "foo": "bar" - }, - "targetingKey": "charlie", - "attributes": { - "age": 50 - }, - "result": { - "value": { - "integer": 2, - "string": "two", - "float": 2.0 - }, - "variant": "two", - "flagMetadata": { - "allocationKey": "50/50 split", - "variationType": "object", - "doLog": true - } - } - }, - { - "flag": "json-config-flag", - "variationType": "JSON", - "defaultValue": { - "foo": "bar" - }, - "targetingKey": "diana", - "attributes": { - "Force Empty": true - }, - "result": { - "value": {}, - "variant": "empty", - "flagMetadata": { - "allocationKey": "Optionally Force Empty", - "variationType": "object", - "doLog": true - } - } - } -] diff --git a/dd-smoke-tests/openfeature/src/test/resources/data/test-no-allocations-flag.json b/dd-smoke-tests/openfeature/src/test/resources/data/test-no-allocations-flag.json deleted file mode 100644 index 45867e5897c..00000000000 --- a/dd-smoke-tests/openfeature/src/test/resources/data/test-no-allocations-flag.json +++ /dev/null @@ -1,52 +0,0 @@ -[ - { - "flag": "no_allocations_flag", - "variationType": "JSON", - "defaultValue": { - "message": "Hello, world!" - }, - "targetingKey": "alice", - "attributes": { - "email": "alice@mycompany.com", - "country": "US" - }, - "result": { - "value": { - "message": "Hello, world!" - } - } - }, - { - "flag": "no_allocations_flag", - "variationType": "JSON", - "defaultValue": { - "message": "Hello, world!" - }, - "targetingKey": "bob", - "attributes": { - "email": "bob@example.com", - "country": "Canada" - }, - "result": { - "value": { - "message": "Hello, world!" - } - } - }, - { - "flag": "no_allocations_flag", - "variationType": "JSON", - "defaultValue": { - "message": "Hello, world!" - }, - "targetingKey": "charlie", - "attributes": { - "age": 50 - }, - "result": { - "value": { - "message": "Hello, world!" - } - } - } -] diff --git a/dd-smoke-tests/openfeature/src/test/resources/data/test-special-characters.json b/dd-smoke-tests/openfeature/src/test/resources/data/test-special-characters.json deleted file mode 100644 index 59ef5cbe87d..00000000000 --- a/dd-smoke-tests/openfeature/src/test/resources/data/test-special-characters.json +++ /dev/null @@ -1,78 +0,0 @@ -[ - { - "flag": "special-characters", - "variationType": "JSON", - "defaultValue": {}, - "targetingKey": "ash", - "attributes": {}, - "result": { - "value": { - "a": "kümmert", - "b": "schön" - }, - "variant": "de", - "flagMetadata": { - "allocationKey": "allocation-test", - "variationType": "object", - "doLog": true - } - } - }, - { - "flag": "special-characters", - "variationType": "JSON", - "defaultValue": {}, - "targetingKey": "ben", - "attributes": {}, - "result": { - "value": { - "a": "піклуватися", - "b": "любов" - }, - "variant": "ua", - "flagMetadata": { - "allocationKey": "allocation-test", - "variationType": "object", - "doLog": true - } - } - }, - { - "flag": "special-characters", - "variationType": "JSON", - "defaultValue": {}, - "targetingKey": "cameron", - "attributes": {}, - "result": { - "value": { - "a": "照顾", - "b": "漂亮" - }, - "variant": "zh", - "flagMetadata": { - "allocationKey": "allocation-test", - "variationType": "object", - "doLog": true - } - } - }, - { - "flag": "special-characters", - "variationType": "JSON", - "defaultValue": {}, - "targetingKey": "darryl", - "attributes": {}, - "result": { - "value": { - "a": "🤗", - "b": "🌸" - }, - "variant": "emoji", - "flagMetadata": { - "allocationKey": "allocation-test", - "variationType": "object", - "doLog": true - } - } - } -] diff --git a/dd-smoke-tests/openfeature/src/test/resources/data/test-string-with-special-characters.json b/dd-smoke-tests/openfeature/src/test/resources/data/test-string-with-special-characters.json deleted file mode 100644 index 27d063122c0..00000000000 --- a/dd-smoke-tests/openfeature/src/test/resources/data/test-string-with-special-characters.json +++ /dev/null @@ -1,1190 +0,0 @@ -[ - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_spaces", - "attributes": { - "string_with_spaces": true - }, - "result": { - "value": " a b c d e f ", - "variant": "string_with_spaces", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_spaces", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_one_space", - "attributes": { - "string_with_only_one_space": true - }, - "result": { - "value": " ", - "variant": "string_with_only_one_space", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_one_space", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_multiple_spaces", - "attributes": { - "string_with_only_multiple_spaces": true - }, - "result": { - "value": " ", - "variant": "string_with_only_multiple_spaces", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_multiple_spaces", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_dots", - "attributes": { - "string_with_dots": true - }, - "result": { - "value": ".a.b.c.d.e.f.", - "variant": "string_with_dots", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_dots", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_one_dot", - "attributes": { - "string_with_only_one_dot": true - }, - "result": { - "value": ".", - "variant": "string_with_only_one_dot", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_one_dot", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_multiple_dots", - "attributes": { - "string_with_only_multiple_dots": true - }, - "result": { - "value": ".......", - "variant": "string_with_only_multiple_dots", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_multiple_dots", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_comas", - "attributes": { - "string_with_comas": true - }, - "result": { - "value": ",a,b,c,d,e,f,", - "variant": "string_with_comas", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_comas", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_one_coma", - "attributes": { - "string_with_only_one_coma": true - }, - "result": { - "value": ",", - "variant": "string_with_only_one_coma", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_one_coma", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_multiple_comas", - "attributes": { - "string_with_only_multiple_comas": true - }, - "result": { - "value": ",,,,,,,", - "variant": "string_with_only_multiple_comas", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_multiple_comas", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_colons", - "attributes": { - "string_with_colons": true - }, - "result": { - "value": ":a:b:c:d:e:f:", - "variant": "string_with_colons", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_colons", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_one_colon", - "attributes": { - "string_with_only_one_colon": true - }, - "result": { - "value": ":", - "variant": "string_with_only_one_colon", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_one_colon", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_multiple_colons", - "attributes": { - "string_with_only_multiple_colons": true - }, - "result": { - "value": ":::::::", - "variant": "string_with_only_multiple_colons", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_multiple_colons", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_semicolons", - "attributes": { - "string_with_semicolons": true - }, - "result": { - "value": ";a;b;c;d;e;f;", - "variant": "string_with_semicolons", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_semicolons", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_one_semicolon", - "attributes": { - "string_with_only_one_semicolon": true - }, - "result": { - "value": ";", - "variant": "string_with_only_one_semicolon", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_one_semicolon", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_multiple_semicolons", - "attributes": { - "string_with_only_multiple_semicolons": true - }, - "result": { - "value": ";;;;;;;", - "variant": "string_with_only_multiple_semicolons", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_multiple_semicolons", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_slashes", - "attributes": { - "string_with_slashes": true - }, - "result": { - "value": "/a/b/c/d/e/f/", - "variant": "string_with_slashes", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_slashes", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_one_slash", - "attributes": { - "string_with_only_one_slash": true - }, - "result": { - "value": "/", - "variant": "string_with_only_one_slash", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_one_slash", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_multiple_slashes", - "attributes": { - "string_with_only_multiple_slashes": true - }, - "result": { - "value": "///////", - "variant": "string_with_only_multiple_slashes", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_multiple_slashes", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_dashes", - "attributes": { - "string_with_dashes": true - }, - "result": { - "value": "-a-b-c-d-e-f-", - "variant": "string_with_dashes", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_dashes", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_one_dash", - "attributes": { - "string_with_only_one_dash": true - }, - "result": { - "value": "-", - "variant": "string_with_only_one_dash", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_one_dash", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_multiple_dashes", - "attributes": { - "string_with_only_multiple_dashes": true - }, - "result": { - "value": "-------", - "variant": "string_with_only_multiple_dashes", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_multiple_dashes", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_underscores", - "attributes": { - "string_with_underscores": true - }, - "result": { - "value": "_a_b_c_d_e_f_", - "variant": "string_with_underscores", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_underscores", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_one_underscore", - "attributes": { - "string_with_only_one_underscore": true - }, - "result": { - "value": "_", - "variant": "string_with_only_one_underscore", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_one_underscore", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_multiple_underscores", - "attributes": { - "string_with_only_multiple_underscores": true - }, - "result": { - "value": "_______", - "variant": "string_with_only_multiple_underscores", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_multiple_underscores", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_plus_signs", - "attributes": { - "string_with_plus_signs": true - }, - "result": { - "value": "+a+b+c+d+e+f+", - "variant": "string_with_plus_signs", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_plus_signs", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_one_plus_sign", - "attributes": { - "string_with_only_one_plus_sign": true - }, - "result": { - "value": "+", - "variant": "string_with_only_one_plus_sign", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_one_plus_sign", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_multiple_plus_signs", - "attributes": { - "string_with_only_multiple_plus_signs": true - }, - "result": { - "value": "+++++++", - "variant": "string_with_only_multiple_plus_signs", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_multiple_plus_signs", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_equal_signs", - "attributes": { - "string_with_equal_signs": true - }, - "result": { - "value": "=a=b=c=d=e=f=", - "variant": "string_with_equal_signs", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_equal_signs", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_one_equal_sign", - "attributes": { - "string_with_only_one_equal_sign": true - }, - "result": { - "value": "=", - "variant": "string_with_only_one_equal_sign", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_one_equal_sign", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_multiple_equal_signs", - "attributes": { - "string_with_only_multiple_equal_signs": true - }, - "result": { - "value": "=======", - "variant": "string_with_only_multiple_equal_signs", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_multiple_equal_signs", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_dollar_signs", - "attributes": { - "string_with_dollar_signs": true - }, - "result": { - "value": "$a$b$c$d$e$f$", - "variant": "string_with_dollar_signs", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_dollar_signs", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_one_dollar_sign", - "attributes": { - "string_with_only_one_dollar_sign": true - }, - "result": { - "value": "$", - "variant": "string_with_only_one_dollar_sign", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_one_dollar_sign", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_multiple_dollar_signs", - "attributes": { - "string_with_only_multiple_dollar_signs": true - }, - "result": { - "value": "$$$$$$$", - "variant": "string_with_only_multiple_dollar_signs", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_multiple_dollar_signs", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_at_signs", - "attributes": { - "string_with_at_signs": true - }, - "result": { - "value": "@a@b@c@d@e@f@", - "variant": "string_with_at_signs", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_at_signs", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_one_at_sign", - "attributes": { - "string_with_only_one_at_sign": true - }, - "result": { - "value": "@", - "variant": "string_with_only_one_at_sign", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_one_at_sign", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_multiple_at_signs", - "attributes": { - "string_with_only_multiple_at_signs": true - }, - "result": { - "value": "@@@@@@@", - "variant": "string_with_only_multiple_at_signs", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_multiple_at_signs", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_amp_signs", - "attributes": { - "string_with_amp_signs": true - }, - "result": { - "value": "&a&b&c&d&e&f&", - "variant": "string_with_amp_signs", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_amp_signs", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_one_amp_sign", - "attributes": { - "string_with_only_one_amp_sign": true - }, - "result": { - "value": "&", - "variant": "string_with_only_one_amp_sign", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_one_amp_sign", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_multiple_amp_signs", - "attributes": { - "string_with_only_multiple_amp_signs": true - }, - "result": { - "value": "&&&&&&&", - "variant": "string_with_only_multiple_amp_signs", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_multiple_amp_signs", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_hash_signs", - "attributes": { - "string_with_hash_signs": true - }, - "result": { - "value": "#a#b#c#d#e#f#", - "variant": "string_with_hash_signs", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_hash_signs", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_one_hash_sign", - "attributes": { - "string_with_only_one_hash_sign": true - }, - "result": { - "value": "#", - "variant": "string_with_only_one_hash_sign", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_one_hash_sign", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_multiple_hash_signs", - "attributes": { - "string_with_only_multiple_hash_signs": true - }, - "result": { - "value": "#######", - "variant": "string_with_only_multiple_hash_signs", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_multiple_hash_signs", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_percentage_signs", - "attributes": { - "string_with_percentage_signs": true - }, - "result": { - "value": "%a%b%c%d%e%f%", - "variant": "string_with_percentage_signs", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_percentage_signs", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_one_percentage_sign", - "attributes": { - "string_with_only_one_percentage_sign": true - }, - "result": { - "value": "%", - "variant": "string_with_only_one_percentage_sign", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_one_percentage_sign", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_multiple_percentage_signs", - "attributes": { - "string_with_only_multiple_percentage_signs": true - }, - "result": { - "value": "%%%%%%%", - "variant": "string_with_only_multiple_percentage_signs", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_multiple_percentage_signs", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_tilde_signs", - "attributes": { - "string_with_tilde_signs": true - }, - "result": { - "value": "~a~b~c~d~e~f~", - "variant": "string_with_tilde_signs", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_tilde_signs", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_one_tilde_sign", - "attributes": { - "string_with_only_one_tilde_sign": true - }, - "result": { - "value": "~", - "variant": "string_with_only_one_tilde_sign", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_one_tilde_sign", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_multiple_tilde_signs", - "attributes": { - "string_with_only_multiple_tilde_signs": true - }, - "result": { - "value": "~~~~~~~", - "variant": "string_with_only_multiple_tilde_signs", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_multiple_tilde_signs", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_asterix_signs", - "attributes": { - "string_with_asterix_signs": true - }, - "result": { - "value": "*a*b*c*d*e*f*", - "variant": "string_with_asterix_signs", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_asterix_signs", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_one_asterix_sign", - "attributes": { - "string_with_only_one_asterix_sign": true - }, - "result": { - "value": "*", - "variant": "string_with_only_one_asterix_sign", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_one_asterix_sign", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_multiple_asterix_signs", - "attributes": { - "string_with_only_multiple_asterix_signs": true - }, - "result": { - "value": "*******", - "variant": "string_with_only_multiple_asterix_signs", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_multiple_asterix_signs", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_single_quotes", - "attributes": { - "string_with_single_quotes": true - }, - "result": { - "value": "'a'b'c'd'e'f'", - "variant": "string_with_single_quotes", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_single_quotes", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_one_single_quote", - "attributes": { - "string_with_only_one_single_quote": true - }, - "result": { - "value": "'", - "variant": "string_with_only_one_single_quote", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_one_single_quote", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_multiple_single_quotes", - "attributes": { - "string_with_only_multiple_single_quotes": true - }, - "result": { - "value": "'''''''", - "variant": "string_with_only_multiple_single_quotes", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_multiple_single_quotes", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_question_marks", - "attributes": { - "string_with_question_marks": true - }, - "result": { - "value": "?a?b?c?d?e?f?", - "variant": "string_with_question_marks", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_question_marks", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_one_question_mark", - "attributes": { - "string_with_only_one_question_mark": true - }, - "result": { - "value": "?", - "variant": "string_with_only_one_question_mark", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_one_question_mark", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_multiple_question_marks", - "attributes": { - "string_with_only_multiple_question_marks": true - }, - "result": { - "value": "???????", - "variant": "string_with_only_multiple_question_marks", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_multiple_question_marks", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_exclamation_marks", - "attributes": { - "string_with_exclamation_marks": true - }, - "result": { - "value": "!a!b!c!d!e!f!", - "variant": "string_with_exclamation_marks", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_exclamation_marks", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_one_exclamation_mark", - "attributes": { - "string_with_only_one_exclamation_mark": true - }, - "result": { - "value": "!", - "variant": "string_with_only_one_exclamation_mark", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_one_exclamation_mark", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_multiple_exclamation_marks", - "attributes": { - "string_with_only_multiple_exclamation_marks": true - }, - "result": { - "value": "!!!!!!!", - "variant": "string_with_only_multiple_exclamation_marks", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_multiple_exclamation_marks", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_opening_parentheses", - "attributes": { - "string_with_opening_parentheses": true - }, - "result": { - "value": "(a(b(c(d(e(f(", - "variant": "string_with_opening_parentheses", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_opening_parentheses", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_one_opening_parenthese", - "attributes": { - "string_with_only_one_opening_parenthese": true - }, - "result": { - "value": "(", - "variant": "string_with_only_one_opening_parenthese", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_one_opening_parenthese", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_multiple_opening_parentheses", - "attributes": { - "string_with_only_multiple_opening_parentheses": true - }, - "result": { - "value": "(((((((", - "variant": "string_with_only_multiple_opening_parentheses", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_multiple_opening_parentheses", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_closing_parentheses", - "attributes": { - "string_with_closing_parentheses": true - }, - "result": { - "value": ")a)b)c)d)e)f)", - "variant": "string_with_closing_parentheses", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_closing_parentheses", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_one_closing_parenthese", - "attributes": { - "string_with_only_one_closing_parenthese": true - }, - "result": { - "value": ")", - "variant": "string_with_only_one_closing_parenthese", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_one_closing_parenthese", - "variationType": "string", - "doLog": true - } - } - }, - { - "flag": "string_flag_with_special_characters", - "variationType": "STRING", - "defaultValue": "default_value", - "targetingKey": "string_with_only_multiple_closing_parentheses", - "attributes": { - "string_with_only_multiple_closing_parentheses": true - }, - "result": { - "value": ")))))))", - "variant": "string_with_only_multiple_closing_parentheses", - "flagMetadata": { - "allocationKey": "allocation-test-string_with_only_multiple_closing_parentheses", - "variationType": "string", - "doLog": true - } - } - } -] diff --git a/dd-smoke-tests/openfeature/src/test/resources/ffe-system-test-data b/dd-smoke-tests/openfeature/src/test/resources/ffe-system-test-data new file mode 160000 index 00000000000..4e2492b83e4 --- /dev/null +++ b/dd-smoke-tests/openfeature/src/test/resources/ffe-system-test-data @@ -0,0 +1 @@ +Subproject commit 4e2492b83e450e2d5746812e9e36649ff906f6c7 From 12c4a5737b3af67bf92fb07ecb81801eb7b000ae Mon Sep 17 00:00:00 2001 From: Leo Romanovsky Date: Tue, 12 May 2026 15:09:01 -0400 Subject: [PATCH 2/6] Catch up FFE missing flag behavior --- .../main/java/datadog/trace/api/openfeature/DDEvaluator.java | 5 ++++- .../java/datadog/trace/api/openfeature/DDEvaluatorTest.java | 3 +-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/products/feature-flagging/feature-flagging-api/src/main/java/datadog/trace/api/openfeature/DDEvaluator.java b/products/feature-flagging/feature-flagging-api/src/main/java/datadog/trace/api/openfeature/DDEvaluator.java index dcfe62db147..00be8bd069a 100644 --- a/products/feature-flagging/feature-flagging-api/src/main/java/datadog/trace/api/openfeature/DDEvaluator.java +++ b/products/feature-flagging/feature-flagging-api/src/main/java/datadog/trace/api/openfeature/DDEvaluator.java @@ -91,7 +91,10 @@ public ProviderEvaluation evaluate( final Flag flag = config.flags.get(key); if (flag == null) { - return error(defaultValue, ErrorCode.FLAG_NOT_FOUND); + return ProviderEvaluation.builder() + .value(defaultValue) + .reason(Reason.DEFAULT.name()) + .build(); } if (!flag.enabled) { diff --git a/products/feature-flagging/feature-flagging-api/src/test/java/datadog/trace/api/openfeature/DDEvaluatorTest.java b/products/feature-flagging/feature-flagging-api/src/test/java/datadog/trace/api/openfeature/DDEvaluatorTest.java index f13f8d2a2ba..936dd29f593 100644 --- a/products/feature-flagging/feature-flagging-api/src/test/java/datadog/trace/api/openfeature/DDEvaluatorTest.java +++ b/products/feature-flagging/feature-flagging-api/src/test/java/datadog/trace/api/openfeature/DDEvaluatorTest.java @@ -1,6 +1,5 @@ package datadog.trace.api.openfeature; -import static dev.openfeature.sdk.ErrorCode.FLAG_NOT_FOUND; import static dev.openfeature.sdk.ErrorCode.TARGETING_KEY_MISSING; import static dev.openfeature.sdk.Reason.DEFAULT; import static dev.openfeature.sdk.Reason.DISABLED; @@ -238,7 +237,7 @@ private static List> evaluateTestCases() { new TestCase<>("default") .flag("non-existent-flag") .targetingKey("user-123") - .result(new Result<>("default").reason(ERROR.name()).errorCode(FLAG_NOT_FOUND)), + .result(new Result<>("default").reason(DEFAULT.name())), new TestCase<>("default") .flag("disabled-flag") .targetingKey("user-123") From 8c7b1e9e7729e24f6fc9361d835fcd1b8a43a4af Mon Sep 17 00:00:00 2001 From: Leo Romanovsky Date: Tue, 12 May 2026 15:24:21 -0400 Subject: [PATCH 3/6] Align Java smoke fixtures with canonical schema --- .../springboot/OpenFeatureProviderSmokeTest.groovy | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/dd-smoke-tests/openfeature/src/test/groovy/datadog/smoketest/springboot/OpenFeatureProviderSmokeTest.groovy b/dd-smoke-tests/openfeature/src/test/groovy/datadog/smoketest/springboot/OpenFeatureProviderSmokeTest.groovy index 6c5d5f29e1a..bfa9a9ad668 100644 --- a/dd-smoke-tests/openfeature/src/test/groovy/datadog/smoketest/springboot/OpenFeatureProviderSmokeTest.groovy +++ b/dd-smoke-tests/openfeature/src/test/groovy/datadog/smoketest/springboot/OpenFeatureProviderSmokeTest.groovy @@ -68,8 +68,9 @@ class OpenFeatureProviderSmokeTest extends AbstractServerSmokeTest { setRemoteConfig("datadog/2/FFE_FLAGS/1/config", rcPayload) final url = "http://localhost:${httpPort}/openfeature/evaluate" final testCases = parseTestCases().findAll { - it.result.flagMetadata?.doLog + it.flag == 'numeric_flag' } + assert !testCases.isEmpty() when: final responses = testCases.collect { @@ -116,9 +117,13 @@ class OpenFeatureProviderSmokeTest extends AbstractServerSmokeTest { response.code() == 200 final responseBody = new JsonSlurper().parse(response.body().byteStream()) responseBody.value == testCase.result.value - responseBody.variant == testCase.result.variant responseBody.reason == testCase.result.reason - responseBody.flagMetadata?.allocationKey == testCase.result.flagMetadata?.allocationKey + if (testCase.result.containsKey('variant')) { + assert responseBody.variant == testCase.result.variant + } + if (testCase.result.flagMetadata?.allocationKey) { + assert responseBody.flagMetadata?.allocationKey == testCase.result.flagMetadata?.allocationKey + } where: testCase << parseTestCases() From afd889bafe9b7cbd4ead81de631dd6bb8f3a862e Mon Sep 17 00:00:00 2001 From: Leo Romanovsky Date: Tue, 12 May 2026 15:54:41 -0400 Subject: [PATCH 4/6] Use canonical fixtures in Java evaluator tests --- .../api/openfeature/DDEvaluatorTest.java | 1321 +++-------------- .../trace/api/openfeature/util/TestCase.java | 114 -- 2 files changed, 176 insertions(+), 1259 deletions(-) delete mode 100644 products/feature-flagging/feature-flagging-api/src/test/java/datadog/trace/api/openfeature/util/TestCase.java diff --git a/products/feature-flagging/feature-flagging-api/src/test/java/datadog/trace/api/openfeature/DDEvaluatorTest.java b/products/feature-flagging/feature-flagging-api/src/test/java/datadog/trace/api/openfeature/DDEvaluatorTest.java index 936dd29f593..d707d3bf5f8 100644 --- a/products/feature-flagging/feature-flagging-api/src/test/java/datadog/trace/api/openfeature/DDEvaluatorTest.java +++ b/products/feature-flagging/feature-flagging-api/src/test/java/datadog/trace/api/openfeature/DDEvaluatorTest.java @@ -1,12 +1,6 @@ package datadog.trace.api.openfeature; -import static dev.openfeature.sdk.ErrorCode.TARGETING_KEY_MISSING; -import static dev.openfeature.sdk.Reason.DEFAULT; -import static dev.openfeature.sdk.Reason.DISABLED; import static dev.openfeature.sdk.Reason.ERROR; -import static dev.openfeature.sdk.Reason.SPLIT; -import static dev.openfeature.sdk.Reason.STATIC; -import static dev.openfeature.sdk.Reason.TARGETING_MATCH; import static java.util.Arrays.asList; import static java.util.Collections.emptyList; import static java.util.Collections.emptyMap; @@ -14,71 +8,54 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.hasEntry; -import static org.hamcrest.Matchers.oneOf; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import datadog.trace.api.featureflag.FeatureFlaggingGateway; -import datadog.trace.api.featureflag.exposure.ExposureEvent; -import datadog.trace.api.featureflag.ufc.v1.Allocation; -import datadog.trace.api.featureflag.ufc.v1.ConditionConfiguration; -import datadog.trace.api.featureflag.ufc.v1.ConditionOperator; +import com.squareup.moshi.JsonAdapter; +import com.squareup.moshi.JsonDataException; +import com.squareup.moshi.JsonReader; +import com.squareup.moshi.JsonWriter; +import com.squareup.moshi.Moshi; +import com.squareup.moshi.Types; import datadog.trace.api.featureflag.ufc.v1.Flag; -import datadog.trace.api.featureflag.ufc.v1.Rule; import datadog.trace.api.featureflag.ufc.v1.ServerConfiguration; -import datadog.trace.api.featureflag.ufc.v1.Shard; -import datadog.trace.api.featureflag.ufc.v1.ShardRange; -import datadog.trace.api.featureflag.ufc.v1.Split; -import datadog.trace.api.featureflag.ufc.v1.ValueType; -import datadog.trace.api.featureflag.ufc.v1.Variant; -import datadog.trace.api.openfeature.util.TestCase; -import datadog.trace.api.openfeature.util.TestCase.Result; import dev.openfeature.sdk.ErrorCode; import dev.openfeature.sdk.EvaluationContext; import dev.openfeature.sdk.MutableContext; import dev.openfeature.sdk.ProviderEvaluation; import dev.openfeature.sdk.Value; -import java.text.ParseException; -import java.text.SimpleDateFormat; +import java.io.IOException; +import java.lang.reflect.Type; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.time.OffsetDateTime; import java.util.ArrayList; -import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.TimeZone; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; +import java.util.stream.Collectors; +import java.util.stream.Stream; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.junit.jupiter.MockitoExtension; -@ExtendWith(MockitoExtension.class) public class DDEvaluatorTest { - @Captor private ArgumentCaptor exposureEventCaptor; - - private FeatureFlaggingGateway.ExposureListener exposureListener; - - @BeforeEach - public void setup() { - exposureListener = mock(FeatureFlaggingGateway.ExposureListener.class); - FeatureFlaggingGateway.addExposureListener(exposureListener); - } - - @AfterEach - public void tearDown() { - FeatureFlaggingGateway.removeExposureListener(exposureListener); - } + private static final String CANONICAL_FIXTURE_PATH = + "dd-smoke-tests/openfeature/src/test/resources/ffe-system-test-data"; + private static final Moshi MOSHI = new Moshi.Builder().add(Date.class, new DateAdapter()).build(); + private static final JsonAdapter CONFIG_ADAPTER = + MOSHI.adapter(ServerConfiguration.class); + private static final Type FIXTURE_LIST_TYPE = + Types.newParameterizedType(List.class, FixtureCase.class); + private static final JsonAdapter> FIXTURE_LIST_ADAPTER = + MOSHI.adapter(FIXTURE_LIST_TYPE); private static Arguments[] valueMappingTestCases() { return new Arguments[] { @@ -174,7 +151,7 @@ public void testNoAllocations() { details = evaluator.evaluate(Integer.class, "empty-allocation", 23, ctx); assertThat(details.getValue(), equalTo(23)); - assertThat(details.getReason(), equalTo(DEFAULT.name())); + assertThat(details.getReason(), equalTo("DEFAULT")); assertThat(details.getErrorCode(), nullValue()); } @@ -210,1111 +187,128 @@ public void testFlattening( } } - private static List> evaluateTestCases() { - return Arrays.asList( - // OF spec 3.1.1: targeting key is optional; static flags must evaluate successfully without - // it - new TestCase<>("default") - .flag("simple-string") - // no .targetingKey() -- null by default - .result(new Result<>("test-value").reason(STATIC.name()).variant("on")), - // Null targeting key on sharded flag must return TARGETING_KEY_MISSING - new TestCase<>("default") - .flag("shard-flag") - // no .targetingKey() -- null - .result(new Result<>("default").reason(ERROR.name()).errorCode(TARGETING_KEY_MISSING)), - // Null targeting key on rule-only flag (matching on non-id attribute) must succeed - new TestCase<>("default") - .flag("country-rule-flag") - // no .targetingKey() -- null - .context("country", "US") - .result(new Result<>("us-value").reason(TARGETING_MATCH.name()).variant("us")), - // OF.7: Empty string is a valid targeting key - evaluation should proceed as normal - new TestCase<>("default") - .flag("simple-string") - .targetingKey("") - .result(new Result<>("test-value").reason(STATIC.name()).variant("on")), - new TestCase<>("default") - .flag("non-existent-flag") - .targetingKey("user-123") - .result(new Result<>("default").reason(DEFAULT.name())), - new TestCase<>("default") - .flag("disabled-flag") - .targetingKey("user-123") - .result(new Result<>("default").reason(DISABLED.name())), - new TestCase<>("default") - .flag("simple-string") - .targetingKey("user-123") - .result(new Result<>("test-value").reason(STATIC.name()).variant("on")), - new TestCase<>(false) - .flag("boolean-flag") - .targetingKey("user-123") - .result(new Result<>(true).reason(STATIC.name()).variant("enabled")), - new TestCase<>(0) - .flag("integer-flag") - .targetingKey("user-123") - .result(new Result<>(42).reason(STATIC.name()).variant("forty-two")), - new TestCase<>("default") - .flag("rule-based-flag") - .targetingKey("user-premium") - .context("email", "john@company.com") - .result(new Result<>("premium").reason(TARGETING_MATCH.name()).variant("premium")), - new TestCase<>("default") - .flag("rule-based-flag") - .targetingKey("user-basic") - .context("email", "john@gmail.com") - .result(new Result<>("basic").reason(STATIC.name()).variant("basic")), - new TestCase<>("default") - .flag("numeric-rule-flag") - .targetingKey("user-vip") - .context("score", 850) - .result(new Result<>("vip").reason(TARGETING_MATCH.name()).variant("vip")), - new TestCase<>("default") - .flag("null-check-flag") - .targetingKey("user-no-beta") - .result(new Result<>("no-beta").reason(TARGETING_MATCH.name()).variant("no-beta")), - new TestCase<>("default") - .flag("region-flag") - .targetingKey("user-regional") - .context("region", "us-east-1") - .result(new Result<>("regional").reason(TARGETING_MATCH.name()).variant("regional")), - new TestCase<>("default") - .flag("time-based-flag") - .targetingKey("user-regional") - .context("region", "us-east-1") - .result(new Result<>("default").reason(DEFAULT.name())), - new TestCase<>("default") - .flag("shard-flag") - .targetingKey("user-shard-test") - .result( - new Result<>("default") - // Result depends on shard calculation - either match or default - .reason(SPLIT.name(), DEFAULT.name())), - // Type mismatch: STRING flag evaluated as Integer - new TestCase<>(0) - .flag("string-number-flag") - .targetingKey("user-123") - .result(new Result<>(0).reason(ERROR.name()).errorCode(ErrorCode.TYPE_MISMATCH)), - // Type mismatch: STRING flag evaluated as Boolean - new TestCase<>(false) - .flag("simple-string") - .targetingKey("user-123") - .result(new Result<>(false).reason(ERROR.name()).errorCode(ErrorCode.TYPE_MISMATCH)), - // Type mismatch: BOOLEAN flag evaluated as String - new TestCase<>("default") - .flag("boolean-flag") - .targetingKey("user-123") - .result( - new Result<>("default").reason(ERROR.name()).errorCode(ErrorCode.TYPE_MISMATCH)), - // Type mismatch: NUMERIC flag evaluated as Integer - new TestCase<>(0) - .flag("double-flag") - .targetingKey("user-123") - .result(new Result<>(0).reason(ERROR.name()).errorCode(ErrorCode.TYPE_MISMATCH)), - // Type mismatch: INTEGER flag evaluated as Double - new TestCase<>(0.0) - .flag("integer-flag") - .targetingKey("user-123") - .result(new Result<>(0.0).reason(ERROR.name()).errorCode(ErrorCode.TYPE_MISMATCH)), - // Variant stores "not-a-number" for an INTEGER flag; Double.parseDouble fails -> - // PARSE_ERROR - new TestCase<>(0) - .flag("integer-string-variant-flag") - .targetingKey("user-123") - .result(new Result<>(0).reason(ERROR.name()).errorCode(ErrorCode.PARSE_ERROR)), - new TestCase<>("default") - .flag("broken-flag") - .targetingKey("user-123") - .result(new Result<>("default").reason(ERROR.name()).errorCode(ErrorCode.GENERAL)), - new TestCase<>("default") - .flag("lt-flag") - .targetingKey("user-123") - .context("score", 750) - .result(new Result<>("low-score").reason(TARGETING_MATCH.name()).variant("low")), - new TestCase<>("default") - .flag("lte-flag") - .targetingKey("user-123") - .context("score", 800) - .result(new Result<>("medium-score").reason(TARGETING_MATCH.name()).variant("medium")), - new TestCase<>("default") - .flag("gt-flag") - .targetingKey("user-123") - .context("score", 950) - .result(new Result<>("high-score").reason(TARGETING_MATCH.name()).variant("high")), - new TestCase<>("default") - .flag("not-matches-flag") - .targetingKey("user-123") - .context("email", "user@yahoo.com") - .result(new Result<>("external").reason(TARGETING_MATCH.name()).variant("external")), - new TestCase<>("default") - .flag("not-one-of-flag") - .targetingKey("user-123") - .context("region", "ap-south-1") - .result(new Result<>("other-region").reason(TARGETING_MATCH.name()).variant("other")), - new TestCase<>("default") - .flag("double-equals-flag") - .targetingKey("user-123") - .context("rate", 3.14159) - .result(new Result<>("pi-value").reason(TARGETING_MATCH.name()).variant("pi")), - new TestCase<>("default") - .flag("nested-attr-flag") - .targetingKey("user-123") - .context("user.profile.level", "premium") - .result(new Result<>("premium-user").reason(TARGETING_MATCH.name()).variant("premium")), - new TestCase<>("default") - .flag("lt-flag") - .targetingKey("user-123") - .context("score", "not-a-number") - .result( - new Result<>("default").reason(ERROR.name()).errorCode(ErrorCode.TYPE_MISMATCH)), - new TestCase<>("default") - .flag("exposure-flag") - .targetingKey("user-123") - .result( - new Result<>("tracked-value") - .reason(STATIC.name()) - .variant("tracked") - .flagMetadata("allocationKey", "exposure-alloc") - .flagMetadata("doLog", true)), - new TestCase<>("default") - .flag("exposure-logging-flag") - .targetingKey("user-exposure") - .context("feature", "premium") - .result( - new Result<>("logged-value") - .reason(TARGETING_MATCH.name()) - .variant("logged") - .flagMetadata("allocationKey", "logged-alloc") - .flagMetadata("doLog", true)), - new TestCase<>("default") - .flag("double-comparison-flag") - .targetingKey("user-123") - .context("score", 3.14159) - .result(new Result<>("exact-match").reason(TARGETING_MATCH.name()).variant("exact")), - new TestCase<>("default") - .flag("numeric-one-of-flag") - .targetingKey("user-123") - .context("score", 3.14159) - .result( - new Result<>("numeric-matched") - .reason(TARGETING_MATCH.name()) - .variant("numeric-match")), - new TestCase<>("default") - .flag("numeric-not-one-of-flag") - .targetingKey("user-123") - .context("score", 42.0) - .result(new Result<>("not-in-set").reason(TARGETING_MATCH.name()).variant("excluded")), - new TestCase<>("default") - .flag("is-null-false-flag") - .targetingKey("user-123") - .context("attr", "value") - .result(new Result<>("not-null").reason(TARGETING_MATCH.name()).variant("not-null")), - new TestCase<>("default") - .flag("is-null-non-boolean-flag") - .targetingKey("user-123") - .result( - new Result<>("null-match").reason(TARGETING_MATCH.name()).variant("null-match")), - new TestCase<>("default") - .flag("null-attribute-flag") - .targetingKey("user-123") - .result(new Result<>("default").reason(DEFAULT.name())), - new TestCase<>("default") - .flag("not-matches-positive-flag") - .targetingKey("user-123") - .context("email", "user@gmail.com") - .result( - new Result<>("external-email").reason(TARGETING_MATCH.name()).variant("external")), - new TestCase<>("default") - .flag("not-one-of-positive-flag") - .targetingKey("user-123") - .context("region", "ap-south-1") - .result(new Result<>("other-region").reason(TARGETING_MATCH.name()).variant("other")), - new TestCase<>("default") - .flag("false-numeric-comparisons-flag") - .targetingKey("user-123") - .context("score", 750) - .result(new Result<>("default").reason(DEFAULT.name())), - new TestCase<>("default") - .flag("empty-splits-flag") - .targetingKey("user-123") - .result(new Result<>("default").reason(DEFAULT.name())), - new TestCase<>("default") - .flag("empty-conditions-flag") - .targetingKey("user-123") - .result(new Result<>("default").reason(DEFAULT.name())), - new TestCase<>("default") - .flag("shard-matching-flag") - .targetingKey("specific-key-that-matches-shard") - .result(new Result<>("shard-matched").reason(SPLIT.name()).variant("matched")), - new TestCase<>("default") - .flag("future-allocation-flag") - .targetingKey("user-123") - .result(new Result<>("default").reason(DEFAULT.name())), - new TestCase<>("default") - .flag("id-attribute-flag") - .targetingKey("user-special-id") - .result(new Result<>("id-resolved").reason(TARGETING_MATCH.name()).variant("id-match")), - new TestCase<>("default") - .flag("non-iterable-condition-flag") - .targetingKey("user-123") - .context("attr", "test-value") - .result(new Result<>("default").reason(DEFAULT.name())), - new TestCase<>("default") - .flag("gt-false-flag") - .targetingKey("user-123") - .context("score", 500) - .result(new Result<>("default").reason(DEFAULT.name())), - new TestCase<>("default") - .flag("lte-false-flag") - .targetingKey("user-123") - .context("score", 600) - .result(new Result<>("default").reason(DEFAULT.name())), - new TestCase<>("default") - .flag("lt-false-flag") - .targetingKey("user-123") - .context("score", 700) - .result(new Result<>("default").reason(DEFAULT.name())), - new TestCase<>("default") - .flag("not-matches-false-flag") - .targetingKey("user-123") - .context("email", "user@company.com") - .result(new Result<>("default").reason(DEFAULT.name())), - new TestCase<>("default") - .flag("not-one-of-false-flag") - .targetingKey("user-123") - .context("region", "us-east-1") - .result(new Result<>("default").reason(DEFAULT.name())), - new TestCase<>("default") - .flag("null-context-values-flag") - .targetingKey("user-123") - .context("nullAttr", (String) null) - .result( - new Result<>("null-handled") - .reason(TARGETING_MATCH.name()) - .variant("null-variant")), - new TestCase<>("default") - .flag("invalid-regex-flag") - .targetingKey("user-123") - .context("email", "user@example.com") - .result(new Result<>("default").reason(ERROR.name()).errorCode(ErrorCode.PARSE_ERROR)), - new TestCase<>("default") - .flag("invalid-regex-not-matches-flag") - .targetingKey("user-123") - .context("email", "user@example.com") - .result(new Result<>("default").reason(ERROR.name()).errorCode(ErrorCode.PARSE_ERROR))); + @Test + public void testCanonicalFixturesArePresent() throws IOException { + assertThat(canonicalTestCases().size(), greaterThan(0)); } - @MethodSource("evaluateTestCases") - @ParameterizedTest - public void testEvaluate(final TestCase testCase) { + @MethodSource("canonicalTestCases") + @ParameterizedTest(name = "{0}") + public void testEvaluateCanonicalFixture(final FixtureCase testCase) throws IOException { final DDEvaluator evaluator = new DDEvaluator(mock(Runnable.class)); - evaluator.accept(createTestConfiguration()); - final ProviderEvaluation details = - evaluator.evaluate(testCase.type, testCase.flag, testCase.defaultValue, testCase.context); - final Result expected = testCase.result; - assertThat(details.getValue(), equalTo(expected.value)); - assertThat(details.getReason(), oneOf(expected.reason)); - assertThat(details.getVariant(), equalTo(expected.variant)); - assertThat(details.getErrorCode(), equalTo(expected.errorCode)); - assertThat(details.getErrorCode(), equalTo(expected.errorCode)); - final String expectedAllocation = (String) expected.flagMetadata.get("allocationKey"); - if (expectedAllocation != null) { - assertThat(details.getFlagMetadata().getString("allocationKey"), equalTo(expectedAllocation)); - } - if (shouldDispatchExposure(expected)) { - verify(exposureListener, times(1)).accept(exposureEventCaptor.capture()); - final ExposureEvent capturedEvent = exposureEventCaptor.getValue(); - assertThat(capturedEvent.flag.key, equalTo(testCase.flag)); - assertThat(capturedEvent.allocation.key, equalTo(expectedAllocation)); - assertThat(capturedEvent.variant.key, equalTo(testCase.result.variant)); - assertThat(capturedEvent.subject.id, equalTo(testCase.context.getTargetingKey())); - for (final Map.Entry entry : testCase.context.asObjectMap().entrySet()) { - assertThat(capturedEvent.subject.attributes, hasEntry(entry.getKey(), entry.getValue())); - } - } else { - verify(exposureListener, times(0)).accept(any(ExposureEvent.class)); - } - } - - private static boolean shouldDispatchExposure(final Result result) { - final Boolean doLog = (Boolean) result.flagMetadata.get("doLog"); - return doLog != null && doLog; - } - - private ServerConfiguration createTestConfiguration() { - final Map flags = new HashMap<>(); - flags.put( - "simple-string", createSimpleFlag("simple-string", ValueType.STRING, "test-value", "on")); - flags.put("boolean-flag", createSimpleFlag("boolean-flag", ValueType.BOOLEAN, true, "enabled")); - flags.put("integer-flag", createSimpleFlag("integer-flag", ValueType.INTEGER, 42, "forty-two")); - flags.put("double-flag", createSimpleFlag("double-flag", ValueType.NUMERIC, 3.14, "pi")); - flags.put( - "string-number-flag", - createSimpleFlag("string-number-flag", ValueType.STRING, "123", "string-num")); - flags.put("disabled-flag", new Flag("disabled-flag", false, ValueType.BOOLEAN, null, null)); - flags.put("rule-based-flag", createRuleBasedFlag()); - flags.put("numeric-rule-flag", createNumericRuleFlag()); - flags.put("null-check-flag", createNullCheckFlag()); - flags.put("region-flag", createOneOfRuleFlag()); - flags.put("time-based-flag", createTimeBasedFlag()); - flags.put("shard-flag", createShardBasedFlag()); - flags.put("broken-flag", createBrokenFlag()); - flags.put("lt-flag", createLessThanFlag()); - flags.put("lte-flag", createLessThanOrEqualFlag()); - flags.put("gt-flag", createGreaterThanFlag()); - flags.put("not-matches-flag", createNotMatchesFlag()); - flags.put("not-one-of-flag", createNotOneOfFlag()); - flags.put("double-equals-flag", createDoubleEqualsFlag()); - flags.put("nested-attr-flag", createNestedAttributeFlag()); - flags.put("exposure-flag", createExposureFlag()); - flags.put("exposure-logging-flag", createExposureLoggingFlag()); - flags.put("double-comparison-flag", createDoubleComparisonFlag()); - flags.put("numeric-one-of-flag", createNumericOneOfFlag()); - flags.put("numeric-not-one-of-flag", createNumericNotOneOfFlag()); - flags.put("is-null-false-flag", createIsNullFalseFlag()); - flags.put("is-null-non-boolean-flag", createIsNullNonBooleanFlag()); - flags.put("null-attribute-flag", createNullAttributeFlag()); - flags.put("not-matches-positive-flag", createNotMatchesPositiveFlag()); - flags.put("not-one-of-positive-flag", createNotOneOfPositiveFlag()); - flags.put("false-numeric-comparisons-flag", createFalseNumericComparisonsFlag()); - flags.put("empty-splits-flag", createEmptySplitsFlag()); - flags.put("empty-conditions-flag", createEmptyConditionsFlag()); - flags.put("shard-matching-flag", createShardMatchingFlag()); - flags.put("future-allocation-flag", createFutureAllocationFlag()); - flags.put("id-attribute-flag", createIdAttributeFlag()); - flags.put("non-iterable-condition-flag", createNonIterableConditionFlag()); - flags.put("gt-false-flag", createGtFalseFlag()); - flags.put("lte-false-flag", createLteFalseFlag()); - flags.put("lt-false-flag", createLtFalseFlag()); - flags.put("not-matches-false-flag", createNotMatchesFalseFlag()); - flags.put("not-one-of-false-flag", createNotOneOfFalseFlag()); - flags.put("null-context-values-flag", createNullContextValuesFlag()); - flags.put("country-rule-flag", createCountryRuleFlag()); - flags.put( - "integer-string-variant-flag", - createSimpleFlag("integer-string-variant-flag", ValueType.INTEGER, "not-a-number", "bad")); - flags.put("invalid-regex-flag", createInvalidRegexFlag()); - flags.put("invalid-regex-not-matches-flag", createInvalidRegexNotMatchesFlag()); - return new ServerConfiguration(null, null, null, flags); - } - - private Flag createSimpleFlag(String key, ValueType type, Object value, String variantKey) { - final Map variants = new HashMap<>(); - variants.put(variantKey, new Variant(variantKey, value)); - final List splits = singletonList(new Split(emptyList(), variantKey, null)); - final List allocations = - singletonList(new Allocation("alloc1", null, null, null, splits, false)); - return new Flag(key, true, type, variants, allocations); - } - - private Flag createRuleBasedFlag() { - final Map variants = new HashMap<>(); - variants.put("premium", new Variant("premium", "premium")); - variants.put("basic", new Variant("basic", "basic")); - - // Rule: email MATCHES @company.com$ -> premium - final List premiumConditions = - singletonList( - new ConditionConfiguration(ConditionOperator.MATCHES, "email", "@company\\.com$")); - final List premiumRules = singletonList(new Rule(premiumConditions)); - final List premiumSplits = singletonList(new Split(emptyList(), "premium", null)); - final Allocation premiumAllocation = - new Allocation("premium-alloc", premiumRules, null, null, premiumSplits, false); - - // Fallback allocation for basic - final List basicSplits = singletonList(new Split(emptyList(), "basic", null)); - final Allocation basicAllocation = - new Allocation("basic-alloc", null, null, null, basicSplits, false); - - final List allocations = asList(premiumAllocation, basicAllocation); - - return new Flag("rule-based-flag", true, ValueType.STRING, variants, allocations); - } - - private Flag createNumericRuleFlag() { - final Map variants = new HashMap<>(); - variants.put("vip", new Variant("vip", "vip")); - variants.put("regular", new Variant("regular", "regular")); - - // Rule: score >= 800 -> vip - final List vipConditions = - singletonList(new ConditionConfiguration(ConditionOperator.GTE, "score", 800)); - final List vipRules = singletonList(new Rule(vipConditions)); - final List vipSplits = singletonList(new Split(emptyList(), "vip", null)); - final Allocation vipAllocation = - new Allocation("vip-alloc", vipRules, null, null, vipSplits, false); - - // Fallback - final List regularSplits = singletonList(new Split(emptyList(), "regular", null)); - final Allocation regularAllocation = - new Allocation("regular-alloc", null, null, null, regularSplits, false); - - return new Flag( - "numeric-rule-flag", - true, - ValueType.STRING, - variants, - asList(vipAllocation, regularAllocation)); - } - - private Flag createNullCheckFlag() { - final Map variants = new HashMap<>(); - variants.put("no-beta", new Variant("no-beta", "no-beta")); - variants.put("has-beta", new Variant("has-beta", "has-beta")); - - // Rule: beta_feature IS_NULL (true) -> no-beta - final List noBetaConditions = - singletonList(new ConditionConfiguration(ConditionOperator.IS_NULL, "beta_feature", true)); - final List noBetaRules = singletonList(new Rule(noBetaConditions)); - final List noBetaSplits = singletonList(new Split(emptyList(), "no-beta", null)); - final Allocation noBetaAllocation = - new Allocation("no-beta-alloc", noBetaRules, null, null, noBetaSplits, false); - - // Fallback - final List hasBetaSplits = singletonList(new Split(emptyList(), "has-beta", null)); - final Allocation hasBetaAllocation = - new Allocation("has-beta-alloc", null, null, null, hasBetaSplits, false); - - return new Flag( - "null-check-flag", - true, - ValueType.STRING, - variants, - asList(noBetaAllocation, hasBetaAllocation)); - } - - private Flag createOneOfRuleFlag() { - final Map variants = new HashMap<>(); - variants.put("regional", new Variant("regional", "regional")); - variants.put("global", new Variant("global", "global")); - - // Rule: region ONE_OF [us-east-1, us-west-2, eu-west-1] -> regional - final List allowedRegions = asList("us-east-1", "us-west-2", "eu-west-1"); - final List regionalConditions = - singletonList( - new ConditionConfiguration(ConditionOperator.ONE_OF, "region", allowedRegions)); - final List regionalRules = singletonList(new Rule(regionalConditions)); - final List regionalSplits = singletonList(new Split(emptyList(), "regional", null)); - final Allocation regionalAllocation = - new Allocation("regional-alloc", regionalRules, null, null, regionalSplits, false); - - // Fallback - final List globalSplits = singletonList(new Split(emptyList(), "global", null)); - final Allocation globalAllocation = - new Allocation("global-alloc", null, null, null, globalSplits, false); - - return new Flag( - "region-flag", - true, - ValueType.STRING, - variants, - asList(regionalAllocation, globalAllocation)); - } - - private Flag createTimeBasedFlag() { - final Map variants = new HashMap<>(); - variants.put("time-limited", new Variant("time-limited", "time-limited")); - - final List splits = singletonList(new Split(emptyList(), "time-limited", null)); - - // Allocation that ended in 2022 (should be inactive) - final List allocations = - singletonList( - new Allocation( - "time-alloc", - null, - parseDate("2022-01-01T00:00:00Z"), - parseDate("2022-12-31T23:59:59Z"), - splits, - false)); - - return new Flag("time-based-flag", true, ValueType.STRING, variants, allocations); - } - - private Flag createShardBasedFlag() { - final Map variants = new HashMap<>(); - variants.put("shard-variant", new Variant("shard-variant", "shard-value")); - - // Create a shard that includes some range - final List ranges = singletonList(new ShardRange(0, 50)); // 0-49 out of 100 - final List shards = singletonList(new Shard("test-salt", ranges, 100)); - - final List splits = singletonList(new Split(shards, "shard-variant", null)); - - final List allocations = - singletonList(new Allocation("shard-alloc", null, null, null, splits, false)); - - return new Flag("shard-flag", true, ValueType.STRING, variants, allocations); - } - - private Flag createBrokenFlag() { - // Create a flag with missing variant - final Map variants = new HashMap<>(); - variants.put("existing", new Variant("existing", "value")); - - final List splits = singletonList(new Split(emptyList(), "missing-variant", null)); - - final List allocations = - singletonList(new Allocation("alloc1", null, null, null, splits, false)); - - return new Flag("broken-flag", true, ValueType.STRING, variants, allocations); - } - - private Flag createComparisonFlag( - String flagKey, - String allocKey, - String variantKey, - String variantValue, - ConditionOperator operator, - String attribute, - Object threshold) { - final Map variants = new HashMap<>(); - variants.put(variantKey, new Variant(variantKey, variantValue)); - - final List conditions = - singletonList(new ConditionConfiguration(operator, attribute, threshold)); - final List rules = singletonList(new Rule(conditions)); - final List splits = singletonList(new Split(emptyList(), variantKey, null)); - final Allocation allocation = new Allocation(allocKey, rules, null, null, splits, false); - - return new Flag(flagKey, true, ValueType.STRING, variants, singletonList(allocation)); - } - - private Flag createLessThanFlag() { - return createComparisonFlag( - "lt-flag", "low-alloc", "low", "low-score", ConditionOperator.LT, "score", 800); - } - - private Flag createLessThanOrEqualFlag() { - return createComparisonFlag( - "lte-flag", "medium-alloc", "medium", "medium-score", ConditionOperator.LTE, "score", 800); - } - - private Flag createGreaterThanFlag() { - return createComparisonFlag( - "gt-flag", "high-alloc", "high", "high-score", ConditionOperator.GT, "score", 900); - } - - private Flag createNotOperatorFlag( - String flagKey, - String allocKey, - String variantKey, - String variantValue, - ConditionOperator operator, - String attribute, - Object value) { - final Map variants = new HashMap<>(); - variants.put(variantKey, new Variant(variantKey, variantValue)); - - final List conditions = - singletonList(new ConditionConfiguration(operator, attribute, value)); - final List rules = singletonList(new Rule(conditions)); - final List splits = singletonList(new Split(emptyList(), variantKey, null)); - final Allocation allocation = new Allocation(allocKey, rules, null, null, splits, false); - - return new Flag(flagKey, true, ValueType.STRING, variants, singletonList(allocation)); - } - - private Flag createNotMatchesFlag() { - return createNotOperatorFlag( - "not-matches-flag", - "external-alloc", - "external", - "external", - ConditionOperator.NOT_MATCHES, - "email", - "@company\\.com$"); - } - - private Flag createNotOneOfFlag() { - final List disallowedRegions = asList("us-east-1", "us-west-2", "eu-west-1"); - return createNotOperatorFlag( - "not-one-of-flag", - "other-alloc", - "other", - "other-region", - ConditionOperator.NOT_ONE_OF, - "region", - disallowedRegions); - } - - private Flag createDoubleEqualsFlag() { - final Map variants = new HashMap<>(); - variants.put("pi", new Variant("pi", "pi-value")); - - // This will test the double comparison in valuesEqual - match exact double value - final List piConditions = - singletonList(new ConditionConfiguration(ConditionOperator.MATCHES, "rate", "3.14159")); - final List piRules = singletonList(new Rule(piConditions)); - final List piSplits = singletonList(new Split(emptyList(), "pi", null)); - final Allocation piAllocation = - new Allocation("pi-alloc", piRules, null, null, piSplits, false); - - return new Flag( - "double-equals-flag", true, ValueType.STRING, variants, singletonList(piAllocation)); - } - - private Flag createNestedAttributeFlag() { - final Map variants = new HashMap<>(); - variants.put("premium", new Variant("premium", "premium-user")); - - // Rule: user.profile.level MATCHES premium -> premium - final List premiumConditions = - singletonList( - new ConditionConfiguration(ConditionOperator.MATCHES, "user.profile.level", "premium")); - final List premiumRules = singletonList(new Rule(premiumConditions)); - final List premiumSplits = singletonList(new Split(emptyList(), "premium", null)); - final Allocation premiumAllocation = - new Allocation("premium-nested-alloc", premiumRules, null, null, premiumSplits, false); - - return new Flag( - "nested-attr-flag", true, ValueType.STRING, variants, singletonList(premiumAllocation)); - } - - private Flag createExposureFlag() { - final Map variants = new HashMap<>(); - variants.put("tracked", new Variant("tracked", "tracked-value")); - - final List splits = singletonList(new Split(emptyList(), "tracked", null)); - // Create allocation with doLog=true to trigger exposure logging - final List allocations = - singletonList(new Allocation("exposure-alloc", null, null, null, splits, true)); - - return new Flag("exposure-flag", true, ValueType.STRING, variants, allocations); - } - - private Flag createDoubleComparisonFlag() { - final Map variants = new HashMap<>(); - variants.put("exact", new Variant("exact", "exact-match")); - - // This flag uses numeric comparison that will trigger the double comparison lambda - final List exactConditions = - singletonList(new ConditionConfiguration(ConditionOperator.LTE, "score", 3.14159)); - final List exactRules = singletonList(new Rule(exactConditions)); - final List exactSplits = singletonList(new Split(emptyList(), "exact", null)); - final Allocation exactAllocation = - new Allocation("exact-alloc", exactRules, null, null, exactSplits, false); - - return new Flag( - "double-comparison-flag", true, ValueType.STRING, variants, singletonList(exactAllocation)); - } - - private Flag createExposureLoggingFlag() { - final Map variants = new HashMap<>(); - variants.put("logged", new Variant("logged", "logged-value")); - - // Rule: feature MATCHES premium -> logged - final List loggedConditions = - singletonList(new ConditionConfiguration(ConditionOperator.MATCHES, "feature", "premium")); - final List loggedRules = singletonList(new Rule(loggedConditions)); - final List loggedSplits = singletonList(new Split(emptyList(), "logged", null)); - // Create allocation with doLog=true to trigger exposure logging and allocationKey method - final Allocation loggedAllocation = - new Allocation("logged-alloc", loggedRules, null, null, loggedSplits, true); - - return new Flag( - "exposure-logging-flag", true, ValueType.STRING, variants, singletonList(loggedAllocation)); - } - - private Flag createNumericOneOfFlag() { - final Map variants = new HashMap<>(); - variants.put("numeric-match", new Variant("numeric-match", "numeric-matched")); - - // Rule: score ONE_OF [3.14159, 2.71828] -> numeric-match - // This will trigger valuesEqual with numeric comparison via lambda$valuesEqual$4 - final List numericValues = asList(3.14159, 2.71828); - final List numericConditions = - singletonList(new ConditionConfiguration(ConditionOperator.ONE_OF, "score", numericValues)); - final List numericRules = singletonList(new Rule(numericConditions)); - final List numericSplits = singletonList(new Split(emptyList(), "numeric-match", null)); - final Allocation numericAllocation = - new Allocation("numeric-alloc", numericRules, null, null, numericSplits, false); + evaluator.accept(loadCanonicalConfiguration()); - return new Flag( - "numeric-one-of-flag", true, ValueType.STRING, variants, singletonList(numericAllocation)); - } - - private Flag createNumericNotOneOfFlag() { - final Map variants = new HashMap<>(); - variants.put("excluded", new Variant("excluded", "not-in-set")); - - // Rule: score NOT_ONE_OF [1.0, 2.0, 3.0] -> excluded - // This will trigger valuesEqual with numeric comparison via lambda$valuesEqual$4 - final List excludedValues = asList(1.0, 2.0, 3.0); - final List excludedConditions = - singletonList( - new ConditionConfiguration(ConditionOperator.NOT_ONE_OF, "score", excludedValues)); - final List excludedRules = singletonList(new Rule(excludedConditions)); - final List excludedSplits = singletonList(new Split(emptyList(), "excluded", null)); - final Allocation excludedAllocation = - new Allocation("excluded-alloc", excludedRules, null, null, excludedSplits, false); - - return new Flag( - "numeric-not-one-of-flag", - true, - ValueType.STRING, - variants, - singletonList(excludedAllocation)); - } - - private Flag createIsNullFalseFlag() { - final Map variants = new HashMap<>(); - variants.put("not-null", new Variant("not-null", "not-null")); - - // Rule: attr IS_NULL false -> not-null (checks if attr is NOT null) - final List notNullConditions = - singletonList(new ConditionConfiguration(ConditionOperator.IS_NULL, "attr", false)); - final List notNullRules = singletonList(new Rule(notNullConditions)); - final List notNullSplits = singletonList(new Split(emptyList(), "not-null", null)); - final Allocation notNullAllocation = - new Allocation("not-null-alloc", notNullRules, null, null, notNullSplits, false); - - return new Flag( - "is-null-false-flag", true, ValueType.STRING, variants, singletonList(notNullAllocation)); - } - - private Flag createIsNullNonBooleanFlag() { - final Map variants = new HashMap<>(); - variants.put("null-match", new Variant("null-match", "null-match")); - - // Rule: missing_attr IS_NULL "string" -> null-match (non-boolean expectedNull value) - final List nullConditions = - singletonList( - new ConditionConfiguration(ConditionOperator.IS_NULL, "missing_attr", "string")); - final List nullRules = singletonList(new Rule(nullConditions)); - final List nullSplits = singletonList(new Split(emptyList(), "null-match", null)); - final Allocation nullAllocation = - new Allocation("null-alloc", nullRules, null, null, nullSplits, false); - - return new Flag( - "is-null-non-boolean-flag", - true, - ValueType.STRING, - variants, - singletonList(nullAllocation)); - } - - private Flag createNullAttributeFlag() { - final Map variants = new HashMap<>(); - variants.put("fallback", new Variant("fallback", "fallback")); - - // Rule: null_attribute MATCHES "test" -> should not match due to null attribute - final List nullAttrConditions = - singletonList(new ConditionConfiguration(ConditionOperator.MATCHES, null, "test")); - final List nullAttrRules = singletonList(new Rule(nullAttrConditions)); - final List nullAttrSplits = singletonList(new Split(emptyList(), "fallback", null)); - final Allocation nullAttrAllocation = - new Allocation("null-attr-alloc", nullAttrRules, null, null, nullAttrSplits, false); - - return new Flag( - "null-attribute-flag", true, ValueType.STRING, variants, singletonList(nullAttrAllocation)); - } - - private Flag createNotMatchesPositiveFlag() { - final Map variants = new HashMap<>(); - variants.put("external", new Variant("external", "external-email")); - - // Rule: email NOT_MATCHES "@company.com" -> external (should match gmail.com) - final List externalConditions = - singletonList( - new ConditionConfiguration(ConditionOperator.NOT_MATCHES, "email", "@company\\.com")); - final List externalRules = singletonList(new Rule(externalConditions)); - final List externalSplits = singletonList(new Split(emptyList(), "external", null)); - final Allocation externalAllocation = - new Allocation("external-alloc", externalRules, null, null, externalSplits, false); - - return new Flag( - "not-matches-positive-flag", - true, - ValueType.STRING, - variants, - singletonList(externalAllocation)); - } - - private Flag createNotOneOfPositiveFlag() { - final Map variants = new HashMap<>(); - variants.put("other", new Variant("other", "other-region")); - - // Rule: region NOT_ONE_OF ["us-east-1", "us-west-2", "eu-west-1"] -> other - final List excludedRegions = asList("us-east-1", "us-west-2", "eu-west-1"); - final List otherConditions = - singletonList( - new ConditionConfiguration(ConditionOperator.NOT_ONE_OF, "region", excludedRegions)); - final List otherRules = singletonList(new Rule(otherConditions)); - final List otherSplits = singletonList(new Split(emptyList(), "other", null)); - final Allocation otherAllocation = - new Allocation("other-alloc", otherRules, null, null, otherSplits, false); - - return new Flag( - "not-one-of-positive-flag", - true, - ValueType.STRING, - variants, - singletonList(otherAllocation)); - } - - private Flag createFalseNumericComparisonsFlag() { - final Map variants = new HashMap<>(); - variants.put("high-score", new Variant("high-score", "high-score")); - - // Rule: score GTE 800 -> high-score (test will provide 750, should fail) - final List highScoreConditions = - singletonList(new ConditionConfiguration(ConditionOperator.GTE, "score", 800)); - final List highScoreRules = singletonList(new Rule(highScoreConditions)); - final List highScoreSplits = singletonList(new Split(emptyList(), "high-score", null)); - final Allocation highScoreAllocation = - new Allocation("high-score-alloc", highScoreRules, null, null, highScoreSplits, false); - - return new Flag( - "false-numeric-comparisons-flag", - true, - ValueType.STRING, - variants, - singletonList(highScoreAllocation)); - } - - private Flag createEmptySplitsFlag() { - final Map variants = new HashMap<>(); - variants.put("default", new Variant("default", "default")); - - // Allocation with null splits - final Allocation allocation = - new Allocation("empty-splits-alloc", null, null, null, null, false); - - return new Flag( - "empty-splits-flag", true, ValueType.STRING, variants, singletonList(allocation)); - } - - private Flag createEmptyConditionsFlag() { - final Map variants = new HashMap<>(); - variants.put("default", new Variant("default", "default")); - - // Rule with empty conditions list - this will be skipped, causing allocation to not match - final Rule emptyConditionsRule = new Rule(emptyList()); - final List splits = singletonList(new Split(emptyList(), "default", null)); - final Allocation allocation = - new Allocation( - "empty-conditions-alloc", - singletonList(emptyConditionsRule), - null, - null, - splits, - false); - - return new Flag( - "empty-conditions-flag", true, ValueType.STRING, variants, singletonList(allocation)); - } - - private Flag createShardMatchingFlag() { - final Map variants = new HashMap<>(); - variants.put("matched", new Variant("matched", "shard-matched")); - - // Create shard that will match the specific targeting key - final List ranges = - singletonList(new ShardRange(0, 100)); // Full range to ensure match - final List shards = singletonList(new Shard("test-salt", ranges, 100)); - final List splits = singletonList(new Split(shards, "matched", null)); - final Allocation allocation = - new Allocation("shard-matching-alloc", null, null, null, splits, false); - - return new Flag( - "shard-matching-flag", true, ValueType.STRING, variants, singletonList(allocation)); - } - - private Flag createFutureAllocationFlag() { - final Map variants = new HashMap<>(); - variants.put("future", new Variant("future", "future-value")); - - final List splits = singletonList(new Split(emptyList(), "future", null)); - - // Allocation that starts in the future (2050) - final Allocation allocation = - new Allocation( - "future-alloc", null, parseDate("2050-01-01T00:00:00Z"), null, splits, false); - - return new Flag( - "future-allocation-flag", true, ValueType.STRING, variants, singletonList(allocation)); - } - - private Flag createIdAttributeFlag() { - final Map variants = new HashMap<>(); - variants.put("id-match", new Variant("id-match", "id-resolved")); - - // Rule that checks for "id" attribute (will use targeting key if not provided) - final List conditions = - singletonList( - new ConditionConfiguration(ConditionOperator.MATCHES, "id", "user-special-id")); - final List rules = singletonList(new Rule(conditions)); - final List splits = singletonList(new Split(emptyList(), "id-match", null)); - final Allocation allocation = new Allocation("id-attr-alloc", rules, null, null, splits, false); - - return new Flag( - "id-attribute-flag", true, ValueType.STRING, variants, singletonList(allocation)); - } - - private Flag createNonIterableConditionFlag() { - final Map variants = new HashMap<>(); - variants.put("no-match", new Variant("no-match", "no-match")); - - // Rule with ONE_OF condition but non-iterable value (String instead of List) - final List conditions = - singletonList(new ConditionConfiguration(ConditionOperator.ONE_OF, "attr", "single-value")); - final List rules = singletonList(new Rule(conditions)); - final List splits = singletonList(new Split(emptyList(), "no-match", null)); - final Allocation allocation = - new Allocation("non-iterable-alloc", rules, null, null, splits, false); - - return new Flag( - "non-iterable-condition-flag", true, ValueType.STRING, variants, singletonList(allocation)); - } - - private Flag createGtFalseFlag() { - return createComparisonFlag( - "gt-false-flag", - "gt-false-alloc", - "high", - "high-value", - ConditionOperator.GT, - "score", - 600); - } - - private Flag createLteFalseFlag() { - return createComparisonFlag( - "lte-false-flag", - "lte-false-alloc", - "low", - "low-value", - ConditionOperator.LTE, - "score", - 500); - } - - private Flag createLtFalseFlag() { - return createComparisonFlag( - "lt-false-flag", - "lt-false-alloc", - "very-low", - "very-low-value", - ConditionOperator.LT, - "score", - 600); - } - - private Flag createNotMatchesFalseFlag() { - final Map variants = new HashMap<>(); - variants.put("internal", new Variant("internal", "internal-email")); - - // Rule: email NOT_MATCHES "@company.com" -> internal (test provides company.com, should fail) - final List conditions = - singletonList( - new ConditionConfiguration(ConditionOperator.NOT_MATCHES, "email", "@company\\.com")); - final List rules = singletonList(new Rule(conditions)); - final List splits = singletonList(new Split(emptyList(), "internal", null)); - final Allocation allocation = - new Allocation("not-matches-false-alloc", rules, null, null, splits, false); + final Class targetType = targetType(testCase.variationType); + final Object defaultValue = mapFixtureValue(targetType, testCase.defaultValue); + final Object expectedValue = mapFixtureValue(targetType, testCase.result.value); + final ProviderEvaluation details = + evaluate(evaluator, targetType, testCase.flag, defaultValue, context(testCase)); - return new Flag( - "not-matches-false-flag", true, ValueType.STRING, variants, singletonList(allocation)); + assertThat(details.getValue(), equalTo(expectedValue)); + assertThat(details.getReason(), equalTo(testCase.result.reason)); + if (testCase.result.variant != null) { + assertThat(details.getVariant(), equalTo(testCase.result.variant)); + } + if (testCase.result.errorCode != null) { + assertThat(details.getErrorCode(), equalTo(ErrorCode.valueOf(testCase.result.errorCode))); + } + if (testCase.result.flagMetadata != null + && testCase.result.flagMetadata.get("allocationKey") != null) { + assertThat( + details.getFlagMetadata().getString("allocationKey"), + equalTo(String.valueOf(testCase.result.flagMetadata.get("allocationKey")))); + } } - private Flag createNotOneOfFalseFlag() { - final Map variants = new HashMap<>(); - variants.put("excluded", new Variant("excluded", "excluded-region")); - - // Rule: region NOT_ONE_OF ["us-east-1", "us-west-2"] -> excluded (test provides us-east-1, - // should fail) - final List excludedRegions = asList("us-east-1", "us-west-2"); - final List conditions = - singletonList( - new ConditionConfiguration(ConditionOperator.NOT_ONE_OF, "region", excludedRegions)); - final List rules = singletonList(new Rule(conditions)); - final List splits = singletonList(new Split(emptyList(), "excluded", null)); - final Allocation allocation = - new Allocation("not-one-of-false-alloc", rules, null, null, splits, false); + @SuppressWarnings({"rawtypes", "unchecked"}) + private static ProviderEvaluation evaluate( + final DDEvaluator evaluator, + final Class targetType, + final String flag, + final Object defaultValue, + final EvaluationContext context) { + return evaluator.evaluate((Class) targetType, flag, defaultValue, context); + } + + private static ServerConfiguration loadCanonicalConfiguration() throws IOException { + return CONFIG_ADAPTER.fromJson(read(fixtureRoot().resolve("ufc-config.json"))); + } + + private static List canonicalTestCases() throws IOException { + final Path evaluationCases = fixtureRoot().resolve("evaluation-cases"); + final List result = new ArrayList<>(); + + try (final Stream paths = Files.list(evaluationCases)) { + final List files = + paths + .filter(path -> path.getFileName().toString().endsWith(".json")) + .sorted((left, right) -> left.getFileName().compareTo(right.getFileName())) + .collect(Collectors.toList()); + for (final Path file : files) { + final List testCases = FIXTURE_LIST_ADAPTER.fromJson(read(file)); + if (testCases == null) { + throw new JsonDataException("Fixture file did not contain an array: " + file); + } + for (int index = 0; index < testCases.size(); index++) { + final FixtureCase testCase = testCases.get(index); + testCase.fileName = file.getFileName().toString(); + testCase.index = index; + result.add(testCase); + } + } + } - return new Flag( - "not-one-of-false-flag", true, ValueType.STRING, variants, singletonList(allocation)); + assertThat(result.size(), greaterThan(0)); + return result; } - private Flag createNullContextValuesFlag() { - final Map variants = new HashMap<>(); - variants.put("null-variant", new Variant("null-variant", "null-handled")); - - // Rule that will handle null context values in flattening - final List conditions = - singletonList(new ConditionConfiguration(ConditionOperator.IS_NULL, "nullAttr", true)); - final List rules = singletonList(new Rule(conditions)); - final List splits = singletonList(new Split(emptyList(), "null-variant", null)); - final Allocation allocation = - new Allocation("null-context-alloc", rules, null, null, splits, false); - - return new Flag( - "null-context-values-flag", true, ValueType.STRING, variants, singletonList(allocation)); + private static Path fixtureRoot() { + Path directory = Paths.get("").toAbsolutePath(); + while (directory != null) { + final Path candidate = directory.resolve(CANONICAL_FIXTURE_PATH); + if (Files.exists(candidate.resolve("ufc-config.json")) + && Files.isDirectory(candidate.resolve("evaluation-cases"))) { + return candidate; + } + directory = directory.getParent(); + } + throw new IllegalStateException("Unable to find canonical FFE fixtures"); } - private Flag createCountryRuleFlag() { - final Map variants = new HashMap<>(); - variants.put("us", new Variant("us", "us-value")); - variants.put("global", new Variant("global", "global-value")); - - // Rule: country ONE_OF ["US"] -> us (no shards, so null targeting key is fine) - final List usCountries = singletonList("US"); - final List usConditions = - singletonList(new ConditionConfiguration(ConditionOperator.ONE_OF, "country", usCountries)); - final List usRules = singletonList(new Rule(usConditions)); - final List usSplits = singletonList(new Split(emptyList(), "us", null)); - final Allocation usAllocation = - new Allocation("us-alloc", usRules, null, null, usSplits, false); - - // Fallback allocation (no rules, no shards) - final List globalSplits = singletonList(new Split(emptyList(), "global", null)); - final Allocation globalAllocation = - new Allocation("global-alloc", null, null, null, globalSplits, false); - - return new Flag( - "country-rule-flag", - true, - ValueType.STRING, - variants, - asList(usAllocation, globalAllocation)); + private static String read(final Path path) throws IOException { + return new String(Files.readAllBytes(path), StandardCharsets.UTF_8); } - private Flag createInvalidRegexFlag() { - final Map variants = new HashMap<>(); - variants.put("matched", new Variant("matched", "matched-value")); - - // Condition with an intentionally invalid regex pattern (unclosed bracket) - final List conditions = - singletonList(new ConditionConfiguration(ConditionOperator.MATCHES, "email", "[invalid")); - final List rules = singletonList(new Rule(conditions)); - final List splits = singletonList(new Split(emptyList(), "matched", null)); - final Allocation allocation = - new Allocation("invalid-regex-alloc", rules, null, null, splits, false); - - return new Flag( - "invalid-regex-flag", true, ValueType.STRING, variants, singletonList(allocation)); + private static EvaluationContext context(final FixtureCase testCase) { + final Map attributes = + testCase.attributes == null ? emptyMap() : testCase.attributes; + final MutableContext context = + new MutableContext(Value.objectToValue(attributes).asStructure().asMap()); + if (testCase.targetingKey != null) { + context.setTargetingKey(testCase.targetingKey); + } + return context; + } + + private static Class targetType(final String variationType) { + switch (variationType) { + case "BOOLEAN": + return Boolean.class; + case "INTEGER": + return Integer.class; + case "NUMERIC": + return Double.class; + case "STRING": + return String.class; + case "JSON": + return Value.class; + default: + throw new IllegalArgumentException("Unsupported variationType: " + variationType); + } } - private Flag createInvalidRegexNotMatchesFlag() { - final Map variants = new HashMap<>(); - variants.put("excluded", new Variant("excluded", "excluded-value")); - - // Condition with an intentionally invalid regex pattern (unclosed bracket) under NOT_MATCHES - final List conditions = - singletonList( - new ConditionConfiguration(ConditionOperator.NOT_MATCHES, "email", "[invalid")); - final List rules = singletonList(new Rule(conditions)); - final List splits = singletonList(new Split(emptyList(), "excluded", null)); - final Allocation allocation = - new Allocation("invalid-regex-not-matches-alloc", rules, null, null, splits, false); - - return new Flag( - "invalid-regex-not-matches-flag", - true, - ValueType.STRING, - variants, - singletonList(allocation)); + private static Object mapFixtureValue(final Class targetType, final Object value) { + return DDEvaluator.mapValue(targetType, value); } private static Map mapOf(final Object... props) { @@ -1328,13 +322,50 @@ private static Map mapOf(final Object... props) { return result; } - private static Date parseDate(String dateString) { - try { - SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); - formatter.setTimeZone(TimeZone.getTimeZone("UTC")); - return formatter.parse(dateString); - } catch (ParseException e) { - throw new RuntimeException("Failed to parse date: " + dateString, e); + private static final class FixtureCase { + Map attributes = emptyMap(); + Object defaultValue; + String flag; + FixtureResult result; + String targetingKey; + String variationType; + transient String fileName; + transient int index; + + @Override + public String toString() { + return fileName + "[" + index + "] flag=" + flag; + } + } + + private static final class FixtureResult { + Object value; + String reason; + String errorCode; + String variant; + Map flagMetadata = emptyMap(); + } + + private static final class DateAdapter extends JsonAdapter { + @Override + public Date fromJson(final JsonReader reader) throws IOException { + if (reader.peek() == JsonReader.Token.NULL) { + return reader.nextNull(); + } + try { + return Date.from(OffsetDateTime.parse(reader.nextString()).toInstant()); + } catch (final Exception ignored) { + return null; + } + } + + @Override + public void toJson(final JsonWriter writer, final Date value) throws IOException { + if (value == null) { + writer.nullValue(); + return; + } + writer.value(value.toInstant().toString()); } } } diff --git a/products/feature-flagging/feature-flagging-api/src/test/java/datadog/trace/api/openfeature/util/TestCase.java b/products/feature-flagging/feature-flagging-api/src/test/java/datadog/trace/api/openfeature/util/TestCase.java deleted file mode 100644 index b19f85bf84e..00000000000 --- a/products/feature-flagging/feature-flagging-api/src/test/java/datadog/trace/api/openfeature/util/TestCase.java +++ /dev/null @@ -1,114 +0,0 @@ -package datadog.trace.api.openfeature.util; - -import dev.openfeature.sdk.ErrorCode; -import dev.openfeature.sdk.MutableContext; -import dev.openfeature.sdk.Structure; -import dev.openfeature.sdk.Value; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class TestCase { - - public Class type; - public String flag; - public E defaultValue; - public final MutableContext context = new MutableContext(); - public Result result; - - @SuppressWarnings("unchecked") - public TestCase(final E defaultValue) { - this.type = (Class) defaultValue.getClass(); - this.defaultValue = defaultValue; - } - - public TestCase flag(String flag) { - this.flag = flag; - return this; - } - - public TestCase targetingKey(final String targetingKey) { - context.setTargetingKey(targetingKey); - return this; - } - - public TestCase context(final String key, final String value) { - context.add(key, value); - return this; - } - - public TestCase context(final String key, final Integer value) { - context.add(key, value); - return this; - } - - public TestCase context(final String key, final Double value) { - context.add(key, value); - return this; - } - - public TestCase context(final String key, final Boolean value) { - context.add(key, value); - return this; - } - - public TestCase context(final String key, final Structure value) { - context.add(key, value); - return this; - } - - public TestCase context(final String key, final List value) { - context.add(key, value); - return this; - } - - public TestCase result(final Result result) { - this.result = result; - return this; - } - - @Override - public String toString() { - return "TestCase{" - + "flag='" - + flag - + '\'' - + ", defaultValue=" - + defaultValue - + ", targetingKey=" - + context.getTargetingKey() - + '}'; - } - - public static class Result { - public E value; - public String variant; - public String[] reason; - public ErrorCode errorCode; - public final Map flagMetadata = new HashMap<>(); - - public Result(final E value) { - this.value = value; - } - - public Result variant(final String variant) { - this.variant = variant; - return this; - } - - public Result errorCode(final ErrorCode errorCode) { - this.errorCode = errorCode; - return this; - } - - public Result reason(final String... reason) { - this.reason = reason; - return this; - } - - public Result flagMetadata(final String name, final Object value) { - flagMetadata.put(name, value); - return this; - } - } -} From e43944c942906ce42bcaa16342f979b789326d30 Mon Sep 17 00:00:00 2001 From: Leo Romanovsky Date: Tue, 12 May 2026 17:07:21 -0400 Subject: [PATCH 5/6] Update FFE fixture submodule --- .../openfeature/src/test/resources/ffe-system-test-data | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dd-smoke-tests/openfeature/src/test/resources/ffe-system-test-data b/dd-smoke-tests/openfeature/src/test/resources/ffe-system-test-data index 4e2492b83e4..50cb3025193 160000 --- a/dd-smoke-tests/openfeature/src/test/resources/ffe-system-test-data +++ b/dd-smoke-tests/openfeature/src/test/resources/ffe-system-test-data @@ -1 +1 @@ -Subproject commit 4e2492b83e450e2d5746812e9e36649ff906f6c7 +Subproject commit 50cb30251936b6ae6ad8477b75f9d618e1fdc2b5 From 14f68be003a3001fdad87a1f828293e8279453a5 Mon Sep 17 00:00:00 2001 From: Leo Romanovsky Date: Tue, 12 May 2026 17:56:26 -0400 Subject: [PATCH 6/6] Fix OpenFeature smoke CodeNarc --- .../smoketest/springboot/OpenFeatureProviderSmokeTest.groovy | 1 - 1 file changed, 1 deletion(-) diff --git a/dd-smoke-tests/openfeature/src/test/groovy/datadog/smoketest/springboot/OpenFeatureProviderSmokeTest.groovy b/dd-smoke-tests/openfeature/src/test/groovy/datadog/smoketest/springboot/OpenFeatureProviderSmokeTest.groovy index bfa9a9ad668..d2c270540f5 100644 --- a/dd-smoke-tests/openfeature/src/test/groovy/datadog/smoketest/springboot/OpenFeatureProviderSmokeTest.groovy +++ b/dd-smoke-tests/openfeature/src/test/groovy/datadog/smoketest/springboot/OpenFeatureProviderSmokeTest.groovy @@ -8,7 +8,6 @@ import groovy.json.JsonOutput import groovy.json.JsonSlurper import java.nio.file.Files import java.nio.file.Paths -import java.util.Comparator import okhttp3.MediaType import okhttp3.Request import okhttp3.RequestBody