From e13251e7df1c5847cdcb1b0517f345da3d3bbe49 Mon Sep 17 00:00:00 2001 From: Jonathan Norris Date: Thu, 21 May 2026 13:41:18 -0400 Subject: [PATCH 1/8] feat: add disabled flag evaluation test scenarios Signed-off-by: Jonathan Norris --- flags/disabled-flags.json | 56 +++++++++++++++++++++++++++++++++++++++ flags/selector-flags.json | 8 ++++++ gherkin/disabled.feature | 44 ++++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+) create mode 100644 flags/disabled-flags.json create mode 100644 gherkin/disabled.feature diff --git a/flags/disabled-flags.json b/flags/disabled-flags.json new file mode 100644 index 0000000..11ad037 --- /dev/null +++ b/flags/disabled-flags.json @@ -0,0 +1,56 @@ +{ + "flags": { + "disabled-boolean-flag": { + "state": "DISABLED", + "variants": { + "on": true, + "off": false + }, + "defaultVariant": "on" + }, + "disabled-string-flag": { + "state": "DISABLED", + "variants": { + "greeting": "hi", + "parting": "bye" + }, + "defaultVariant": "greeting" + }, + "disabled-integer-flag": { + "state": "DISABLED", + "variants": { + "one": 1, + "ten": 10 + }, + "defaultVariant": "ten" + }, + "disabled-float-flag": { + "state": "DISABLED", + "variants": { + "tenth": 0.1, + "half": 0.5 + }, + "defaultVariant": "half" + }, + "disabled-object-flag": { + "state": "DISABLED", + "variants": { + "empty": {}, + "template": { + "showImages": true, + "title": "Check out these pics!", + "imagesPerPage": 100 + } + }, + "defaultVariant": "template" + }, + "cross-flagset-flag": { + "state": "DISABLED", + "variants": { + "on": true, + "off": false + }, + "defaultVariant": "on" + } + } +} diff --git a/flags/selector-flags.json b/flags/selector-flags.json index ee054c3..aa4572c 100644 --- a/flags/selector-flags.json +++ b/flags/selector-flags.json @@ -7,6 +7,14 @@ "bar": "bar" }, "defaultVariant": "foo" + }, + "cross-flagset-flag": { + "state": "ENABLED", + "variants": { + "on": true, + "off": false + }, + "defaultVariant": "on" } } } diff --git a/gherkin/disabled.feature b/gherkin/disabled.feature new file mode 100644 index 0000000..91739be --- /dev/null +++ b/gherkin/disabled.feature @@ -0,0 +1,44 @@ +Feature: Disabled flag evaluation + + # Test coverage for disabled flag behavior. A flag with state=DISABLED resolves + # successfully with reason=DISABLED and no value or variant (SDK uses code default). + # Relates to: https://github.com/open-feature/flagd/issues/1965 + + @rpc @in-process + Scenario Outline: Evaluating a disabled flag returns reason DISABLED and code default + Given an option "cache" of type "CacheType" with value "disabled" + And a stable flagd provider + And a -flag with key "" and a default value "" + When the flag was evaluated with details + Then the resolved details value should be "" + And the reason should be "DISABLED" + + Examples: + | key | type | default | + | disabled-boolean-flag | Boolean | false | + | disabled-string-flag | String | bye | + | disabled-integer-flag | Integer | 1 | + | disabled-float-flag | Float | 0.1 | + + @rpc + Scenario: Bulk evaluation includes disabled flags with reason DISABLED + Given an option "cache" of type "CacheType" with value "disabled" + And a stable flagd provider + When all flags were evaluated in bulk + Then the bulk evaluation result should contain a flag with key "disabled-boolean-flag" and reason "DISABLED" + And the bulk evaluation result should contain a flag with key "boolean-flag" and reason "STATIC" + + @in-process + Scenario Outline: Flag disabled in one flag set, enabled in another + Given an option "cache" of type "CacheType" with value "disabled" + And an option "selector" of type "String" with value "" + And a stable flagd provider + And a Boolean-flag with key "cross-flagset-flag" and a default value "false" + When the flag was evaluated with details + Then the resolved details value should be "" + And the reason should be "" + + Examples: + | selector | resolved_value | reason | + | rawflags/disabled-flags.json | false | DISABLED | + | rawflags/selector-flags.json | true | STATIC | From 56894d29c1f932e2691677f66f634c440a572a4e Mon Sep 17 00:00:00 2001 From: Jonathan Norris Date: Mon, 25 May 2026 10:28:35 -0400 Subject: [PATCH 2/8] fix: add object example and correct cross-flagset selector Signed-off-by: Jonathan Norris --- gherkin/disabled.feature | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gherkin/disabled.feature b/gherkin/disabled.feature index 91739be..21e7ae0 100644 --- a/gherkin/disabled.feature +++ b/gherkin/disabled.feature @@ -19,6 +19,7 @@ Feature: Disabled flag evaluation | disabled-string-flag | String | bye | | disabled-integer-flag | Integer | 1 | | disabled-float-flag | Float | 0.1 | + | disabled-object-flag | Object | {} | @rpc Scenario: Bulk evaluation includes disabled flags with reason DISABLED @@ -40,5 +41,5 @@ Feature: Disabled flag evaluation Examples: | selector | resolved_value | reason | - | rawflags/disabled-flags.json | false | DISABLED | + | flags/allFlags.json | false | DISABLED | | rawflags/selector-flags.json | true | STATIC | From 834ed0684818fa7a0aee9dfd60782cff449bdaa1 Mon Sep 17 00:00:00 2001 From: Jonathan Norris Date: Mon, 25 May 2026 16:06:32 -0400 Subject: [PATCH 3/8] fix: add @disabled tag, drop bulk eval scenario Signed-off-by: Jonathan Norris --- gherkin/disabled.feature | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/gherkin/disabled.feature b/gherkin/disabled.feature index 21e7ae0..3e2d1a8 100644 --- a/gherkin/disabled.feature +++ b/gherkin/disabled.feature @@ -1,3 +1,4 @@ +@disabled Feature: Disabled flag evaluation # Test coverage for disabled flag behavior. A flag with state=DISABLED resolves @@ -21,14 +22,6 @@ Feature: Disabled flag evaluation | disabled-float-flag | Float | 0.1 | | disabled-object-flag | Object | {} | - @rpc - Scenario: Bulk evaluation includes disabled flags with reason DISABLED - Given an option "cache" of type "CacheType" with value "disabled" - And a stable flagd provider - When all flags were evaluated in bulk - Then the bulk evaluation result should contain a flag with key "disabled-boolean-flag" and reason "DISABLED" - And the bulk evaluation result should contain a flag with key "boolean-flag" and reason "STATIC" - @in-process Scenario Outline: Flag disabled in one flag set, enabled in another Given an option "cache" of type "CacheType" with value "disabled" From 5af9e825f9b15506c45c0a5ec6836b44ab82178e Mon Sep 17 00:00:00 2001 From: Jonathan Norris Date: Mon, 25 May 2026 16:07:26 -0400 Subject: [PATCH 4/8] fix: move @in-process to feature level Signed-off-by: Jonathan Norris --- gherkin/disabled.feature | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/gherkin/disabled.feature b/gherkin/disabled.feature index 3e2d1a8..0c22f1b 100644 --- a/gherkin/disabled.feature +++ b/gherkin/disabled.feature @@ -1,11 +1,11 @@ -@disabled +@disabled @in-process Feature: Disabled flag evaluation # Test coverage for disabled flag behavior. A flag with state=DISABLED resolves # successfully with reason=DISABLED and no value or variant (SDK uses code default). # Relates to: https://github.com/open-feature/flagd/issues/1965 - @rpc @in-process + @rpc Scenario Outline: Evaluating a disabled flag returns reason DISABLED and code default Given an option "cache" of type "CacheType" with value "disabled" And a stable flagd provider @@ -22,7 +22,6 @@ Feature: Disabled flag evaluation | disabled-float-flag | Float | 0.1 | | disabled-object-flag | Object | {} | - @in-process Scenario Outline: Flag disabled in one flag set, enabled in another Given an option "cache" of type "CacheType" with value "disabled" And an option "selector" of type "String" with value "" From 53697b24a5433a214bf6fb29ae0ec99332c3e465 Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Mon, 1 Jun 2026 08:38:50 -0400 Subject: [PATCH 5/8] fixup: move rpc annotation, add flag set Signed-off-by: Todd Baert --- evaluator/flags/testkit-flags.json | 44 ++++++++++++++++++++++++++++++ evaluator/gherkin/disabled.feature | 31 +++++++++++++++++++++ flags/selector-flags.json | 3 ++ gherkin/disabled.feature | 3 +- 4 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 evaluator/gherkin/disabled.feature diff --git a/evaluator/flags/testkit-flags.json b/evaluator/flags/testkit-flags.json index fb82a03..cd55c18 100644 --- a/evaluator/flags/testkit-flags.json +++ b/evaluator/flags/testkit-flags.json @@ -655,6 +655,50 @@ "targeting": { "sem_ver": [{"var": "version"}, "="] } + }, + "disabled-boolean-flag": { + "state": "DISABLED", + "variants": { + "on": true, + "off": false + }, + "defaultVariant": "on" + }, + "disabled-string-flag": { + "state": "DISABLED", + "variants": { + "greeting": "hi", + "parting": "bye" + }, + "defaultVariant": "greeting" + }, + "disabled-integer-flag": { + "state": "DISABLED", + "variants": { + "one": 1, + "ten": 10 + }, + "defaultVariant": "ten" + }, + "disabled-float-flag": { + "state": "DISABLED", + "variants": { + "tenth": 0.1, + "half": 0.5 + }, + "defaultVariant": "half" + }, + "disabled-object-flag": { + "state": "DISABLED", + "variants": { + "empty": {}, + "template": { + "showImages": true, + "title": "Check out these pics!", + "imagesPerPage": 100 + } + }, + "defaultVariant": "template" } }, "$evaluators": { diff --git a/evaluator/gherkin/disabled.feature b/evaluator/gherkin/disabled.feature new file mode 100644 index 0000000..13c3455 --- /dev/null +++ b/evaluator/gherkin/disabled.feature @@ -0,0 +1,31 @@ +@disabled +Feature: Evaluator disabled flag evaluation + + # Validates that disabled flags resolve with reason=DISABLED and no value/variant. + # The evaluator omits value and variant; the SDK substitutes the caller-provided default. + # Flags are configured in evaluator/flags/testkit-flags.json. + # Relates to: https://github.com/open-feature/flagd/issues/1965 + + Scenario Outline: Resolve disabled flag returns reason DISABLED with absent value + Given an evaluator + And a -flag with key "" and a fallback value "" + When the flag was evaluated with details + Then the resolved value should be absent + And the reason should be "DISABLED" + + Examples: Boolean evaluations + | key | type | default | + | disabled-boolean-flag | Boolean | false | + + Examples: String evaluations + | key | type | default | + | disabled-string-flag | String | bye | + + Examples: Number evaluations + | key | type | default | + | disabled-integer-flag | Integer | 1 | + | disabled-float-flag | Float | 0.1 | + + Examples: Object evaluations + | key | type | default | + | disabled-object-flag | Object | {} | diff --git a/flags/selector-flags.json b/flags/selector-flags.json index aa4572c..c9afb9a 100644 --- a/flags/selector-flags.json +++ b/flags/selector-flags.json @@ -16,5 +16,8 @@ }, "defaultVariant": "on" } + }, + "metadata": { + "flagSetId": "selector-set" } } diff --git a/gherkin/disabled.feature b/gherkin/disabled.feature index 0c22f1b..763100f 100644 --- a/gherkin/disabled.feature +++ b/gherkin/disabled.feature @@ -1,11 +1,10 @@ -@disabled @in-process +@disabled @in-process @rpc Feature: Disabled flag evaluation # Test coverage for disabled flag behavior. A flag with state=DISABLED resolves # successfully with reason=DISABLED and no value or variant (SDK uses code default). # Relates to: https://github.com/open-feature/flagd/issues/1965 - @rpc Scenario Outline: Evaluating a disabled flag returns reason DISABLED and code default Given an option "cache" of type "CacheType" with value "disabled" And a stable flagd provider From 0bb4ca4bf16c344fdbdd643f8949f205b6d540bc Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Mon, 1 Jun 2026 10:16:06 -0400 Subject: [PATCH 6/8] fixup: use default in evaluator tests Signed-off-by: Todd Baert --- evaluator/gherkin/disabled.feature | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/evaluator/gherkin/disabled.feature b/evaluator/gherkin/disabled.feature index 13c3455..5d9ec43 100644 --- a/evaluator/gherkin/disabled.feature +++ b/evaluator/gherkin/disabled.feature @@ -1,16 +1,16 @@ @disabled Feature: Evaluator disabled flag evaluation - # Validates that disabled flags resolve with reason=DISABLED and no value/variant. - # The evaluator omits value and variant; the SDK substitutes the caller-provided default. + # Validates that disabled flags resolve with reason=DISABLED. The evaluator + # substitutes the caller-provided default value and omits the variant. # Flags are configured in evaluator/flags/testkit-flags.json. # Relates to: https://github.com/open-feature/flagd/issues/1965 - Scenario Outline: Resolve disabled flag returns reason DISABLED with absent value + Scenario Outline: Resolve disabled flag returns reason DISABLED with the default value Given an evaluator And a -flag with key "" and a fallback value "" When the flag was evaluated with details - Then the resolved value should be absent + Then the resolved details value should be "" And the reason should be "DISABLED" Examples: Boolean evaluations From b9929ee0813030c013c89cf025404907b0c234d8 Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Mon, 1 Jun 2026 10:36:10 -0400 Subject: [PATCH 7/8] fixup: formatting Signed-off-by: Todd Baert --- evaluator/gherkin/disabled.feature | 15 +++------------ gherkin/disabled.feature | 3 ++- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/evaluator/gherkin/disabled.feature b/evaluator/gherkin/disabled.feature index 5d9ec43..5edff08 100644 --- a/evaluator/gherkin/disabled.feature +++ b/evaluator/gherkin/disabled.feature @@ -13,19 +13,10 @@ Feature: Evaluator disabled flag evaluation Then the resolved details value should be "" And the reason should be "DISABLED" - Examples: Boolean evaluations + Examples: | key | type | default | | disabled-boolean-flag | Boolean | false | - - Examples: String evaluations - | key | type | default | - | disabled-string-flag | String | bye | - - Examples: Number evaluations - | key | type | default | + | disabled-string-flag | String | bye | | disabled-integer-flag | Integer | 1 | | disabled-float-flag | Float | 0.1 | - - Examples: Object evaluations - | key | type | default | - | disabled-object-flag | Object | {} | + | disabled-object-flag | Object | {} | diff --git a/gherkin/disabled.feature b/gherkin/disabled.feature index 763100f..926238f 100644 --- a/gherkin/disabled.feature +++ b/gherkin/disabled.feature @@ -2,7 +2,8 @@ Feature: Disabled flag evaluation # Test coverage for disabled flag behavior. A flag with state=DISABLED resolves - # successfully with reason=DISABLED and no value or variant (SDK uses code default). + # successfully with reason=DISABLED; the evaluator substitutes the caller-provided + # default value and omits the variant. # Relates to: https://github.com/open-feature/flagd/issues/1965 Scenario Outline: Evaluating a disabled flag returns reason DISABLED and code default From 87928acb69f68e83fb485ef38436837997897381 Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Mon, 1 Jun 2026 12:52:38 -0400 Subject: [PATCH 8/8] fixup: bump flagd base image to v0.16.0 Signed-off-by: Todd Baert --- flagd/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flagd/Dockerfile b/flagd/Dockerfile index 70365a0..d22918e 100644 --- a/flagd/Dockerfile +++ b/flagd/Dockerfile @@ -1,4 +1,4 @@ -ARG FLAGD_BASE_IMAGE=ghcr.io/open-feature/flagd:v0.15.5 +ARG FLAGD_BASE_IMAGE=ghcr.io/open-feature/flagd:v0.16.0 ARG TARGETARCH FROM ${FLAGD_BASE_IMAGE} AS flagd