Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 13 additions & 11 deletions core/validation/flipt.cue
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,21 @@ close({
#Namespace: {
key: string & =~"^[-_,A-Za-z0-9]+$" | *"default"
name?: string & =~"^.+$"
description?: string
description?: string | null
} | string & =~"^[-_,A-Za-z0-9]+$"

#Flag: {
key: string & =~"^[-_,A-Za-z0-9]+$"
name: string & =~"^.+$"
description?: string
description?: string | null
enabled: bool | *false
variants: [...#Variant]
rules: [...#Rule]
if version == "1.1" || version == "1.2" || version == "1.3" || version == "1.4" || version == "1.5" {
type: "BOOLEAN_FLAG_TYPE" | *"VARIANT_FLAG_TYPE"
#FlagBoolean | *{}
if type == "BOOLEAN_FLAG_TYPE" {
#FlagBoolean
}
}
if version == "1.3" || version == "1.4" || version == "1.5" {
metadata: [string]: !=null
Expand All @@ -32,15 +34,15 @@ close({
#FlagBoolean: {
type: "BOOLEAN_FLAG_TYPE"
rollouts: [...{
description?: string
description?: string | null
#Rollout
}]
}

#Variant: {
key: string & =~"^.+$"
name?: string & =~"^.+$"
description?: string
description?: string | null
attachment: {...} | [...] | *null
if version == "1.3" || version == "1.4" || version == "1.5" {
default: bool | *false
Expand Down Expand Up @@ -83,38 +85,38 @@ close({
key: string & =~"^[-_,A-Za-z0-9]+$"
name: string & =~"^.+$"
match_type: "ANY_MATCH_TYPE" | "ALL_MATCH_TYPE"
description?: string
description?: string | null
constraints: [...#Constraint]
}

#Constraint: ({
type: "STRING_COMPARISON_TYPE"
property: string & =~"^.+$"
value?: string
description?: string
description?: string | null
operator: "eq" | "neq" | "empty" | "notempty" | "prefix" | "suffix" | "isoneof" | "isnotoneof" | "contains" | "notcontains"
} | {
type: "NUMBER_COMPARISON_TYPE"
property: string & =~"^.+$"
value?: string
description?: string
description?: string | null
operator: "eq" | "neq" | "present" | "notpresent" | "le" | "lte" | "gt" | "gte" | "isoneof" | "isnotoneof"
} | {
type: "BOOLEAN_COMPARISON_TYPE"
property: string & =~"^.+$"
value?: string
description?: string
description?: string | null
operator: "true" | "false" | "present" | "notpresent"
} | {
type: "DATETIME_COMPARISON_TYPE"
property: string & =~"^.+$"
value?: string
description?: string
description?: string | null
operator: "eq" | "neq" | "present" | "notpresent" | "le" | "lte" | "gt" | "gte"
} | {
type: "ENTITY_ID_COMPARISON_TYPE"
property: string & =~"^.+$"
value?: string
description?: string
description?: string | null
operator: "eq" | "neq" | "empty" | "notempty" | "prefix" | "suffix" | "isoneof" | "isnotoneof" | "contains" | "notcontains"
})
1 change: 1 addition & 0 deletions core/validation/testdata/valid.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ flags:
rollout: 100
- key: boolean
name: Boolean
type: BOOLEAN_FLAG_TYPE
enabled: false
rollouts:
- description: enabled for internal users
Expand Down
1 change: 1 addition & 0 deletions core/validation/testdata/valid_namespace_details_v4.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ flags:
rollout: 100
- key: boolean
name: Boolean
type: BOOLEAN_FLAG_TYPE
description: Boolean flag
enabled: false
rollouts:
Expand Down
45 changes: 45 additions & 0 deletions core/validation/testdata/valid_null_descriptions.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
version: "1.5"
namespace:
key: test_namespace
name: Test Namespace
description: null
flags:
- key: variant_flag_with_null_desc
name: Variant Flag
description: null
enabled: true
type: VARIANT_FLAG_TYPE
variants:
- key: control
name: Control
description: null
- key: treatment
name: Treatment
description: null
rules:
- segment: test-segment
distributions:
- variant: control
rollout: 50
- variant: treatment
rollout: 50
- key: boolean_flag_with_null_rollout_desc
name: Boolean Flag
type: BOOLEAN_FLAG_TYPE
enabled: true
rollouts:
- description: null
threshold:
percentage: 50.0
value: true
segments:
- key: test-segment
name: Test Segment
description: null
match_type: ALL_MATCH_TYPE
constraints:
- type: STRING_COMPARISON_TYPE
property: user_id
operator: eq
value: "123"
description: null
1 change: 1 addition & 0 deletions core/validation/testdata/valid_segments_v2.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ flags:
rollout: 100
- key: boolean
name: Boolean
type: BOOLEAN_FLAG_TYPE
description: Boolean flag
enabled: false
rollouts:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
version: "1.5"
namespace:
key: test_namespace
name: Test Namespace
flags:
- key: variant_flag
name: Variant Flag
description: A variant flag should not require rollouts field
enabled: true
type: VARIANT_FLAG_TYPE
variants:
- key: control
name: Control
description: Control variant
- key: treatment
name: Treatment
description: Treatment variant
rules:
- segment: all-users
distributions:
- variant: control
rollout: 50
- variant: treatment
rollout: 50
segments:
- key: all-users
name: All Users
description: All Users
match_type: ALL_MATCH_TYPE
2 changes: 2 additions & 0 deletions core/validation/testdata/valid_yaml_stream.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ flags:
rollout: 100
- key: boolean
name: Boolean
type: BOOLEAN_FLAG_TYPE
description: Boolean flag
enabled: false
rollouts:
Expand Down Expand Up @@ -73,6 +74,7 @@ flags:
rollout: 100
- key: boolean
name: Boolean
type: BOOLEAN_FLAG_TYPE
description: Boolean flag
enabled: false
rollouts:
Expand Down
35 changes: 35 additions & 0 deletions core/validation/validate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,3 +191,38 @@ func TestValidate_Extended(t *testing.T) {
assert.Equal(t, `flags.1.description: incomplete value =~"^.+$"`, ferr.Message)
assert.Equal(t, file, ferr.Location.File)
}

// TestValidate_NullDescriptions tests that null descriptions are allowed
// in all entities (namespace, flags, variants, segments, constraints, rollouts).
// This test would have caught the bug where CUE schema was rejecting null descriptions.
func TestValidate_NullDescriptions(t *testing.T) {
const file = "testdata/valid_null_descriptions.yaml"
f, err := os.Open(file)
require.NoError(t, err)

defer f.Close()

v, err := NewFeaturesValidator()
require.NoError(t, err)

err = v.Validate(file, f)
assert.NoError(t, err)
}

// TestValidate_VariantFlagWithoutRollouts tests that variant flags
// do not require the rollouts field. This test would have caught the bug
// where the CUE schema incorrectly required rollouts on all flags due to
// the unconditional #FlagBoolean | *{} pattern.
func TestValidate_VariantFlagWithoutRollouts(t *testing.T) {
const file = "testdata/valid_variant_flag_without_rollouts.yaml"
f, err := os.Open(file)
require.NoError(t, err)

defer f.Close()

v, err := NewFeaturesValidator()
require.NoError(t, err)

err = v.Validate(file, f)
assert.NoError(t, err)
}
Loading