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..5edff08 --- /dev/null +++ b/evaluator/gherkin/disabled.feature @@ -0,0 +1,22 @@ +@disabled +Feature: Evaluator disabled flag evaluation + + # 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 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 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 | + | disabled-object-flag | Object | {} | 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 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..c9afb9a 100644 --- a/flags/selector-flags.json +++ b/flags/selector-flags.json @@ -7,6 +7,17 @@ "bar": "bar" }, "defaultVariant": "foo" + }, + "cross-flagset-flag": { + "state": "ENABLED", + "variants": { + "on": true, + "off": false + }, + "defaultVariant": "on" } + }, + "metadata": { + "flagSetId": "selector-set" } } diff --git a/gherkin/disabled.feature b/gherkin/disabled.feature new file mode 100644 index 0000000..926238f --- /dev/null +++ b/gherkin/disabled.feature @@ -0,0 +1,37 @@ +@disabled @in-process @rpc +Feature: Disabled flag evaluation + + # Test coverage for disabled flag behavior. A flag with state=DISABLED resolves + # 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 + 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 | + | disabled-object-flag | Object | {} | + + 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 | + | flags/allFlags.json | false | DISABLED | + | rawflags/selector-flags.json | true | STATIC |