@@ -21,6 +21,7 @@ import (
21
21
"net"
22
22
"net/url"
23
23
"os"
24
+ "strconv"
24
25
"testing"
25
26
"time"
26
27
@@ -93,10 +94,11 @@ func TestConfigFileOtherFields(t *testing.T) {
93
94
94
95
func TestConfigFileFeatureGates (t * testing.T ) {
95
96
testCases := []struct {
96
- name string
97
- serverFeatureGatesJSON string
98
- expectErr bool
99
- expectedFeatures map [featuregate.Feature ]bool
97
+ name string
98
+ serverFeatureGatesJSON string
99
+ experimentalStopGRPCServiceOnDefrag string
100
+ expectErr bool
101
+ expectedFeatures map [featuregate.Feature ]bool
100
102
}{
101
103
{
102
104
name : "default" ,
@@ -106,25 +108,51 @@ func TestConfigFileFeatureGates(t *testing.T) {
106
108
},
107
109
},
108
110
{
109
- name : "set StopGRPCServiceOnDefrag to true" ,
110
- serverFeatureGatesJSON : "StopGRPCServiceOnDefrag=true" ,
111
+ name : "cannot set both experimental flag and feature gate flag" ,
112
+ serverFeatureGatesJSON : "StopGRPCServiceOnDefrag=true" ,
113
+ experimentalStopGRPCServiceOnDefrag : "false" ,
114
+ expectErr : true ,
115
+ },
116
+ {
117
+ name : "ok to set different experimental flag and feature gate flag" ,
118
+ serverFeatureGatesJSON : "DistributedTracing=true" ,
119
+ experimentalStopGRPCServiceOnDefrag : "true" ,
111
120
expectedFeatures : map [featuregate.Feature ]bool {
112
- features .DistributedTracing : false ,
121
+ features .DistributedTracing : true ,
113
122
features .StopGRPCServiceOnDefrag : true ,
114
123
},
115
124
},
116
125
{
117
- name : " set both features to true" ,
118
- serverFeatureGatesJSON : "DistributedTracing=true,StopGRPCServiceOnDefrag= true" ,
126
+ name : "can set feature gate to true from experimental flag " ,
127
+ experimentalStopGRPCServiceOnDefrag : "true" ,
119
128
expectedFeatures : map [featuregate.Feature ]bool {
120
- features .DistributedTracing : true ,
121
129
features .StopGRPCServiceOnDefrag : true ,
130
+ features .DistributedTracing : false ,
122
131
},
123
132
},
124
133
{
125
- name : "error setting unrecognized feature" ,
126
- serverFeatureGatesJSON : "DistributedTracing=true,StopGRPCServiceOnDefragExp=true" ,
127
- expectErr : true ,
134
+ name : "can set feature gate to false from experimental flag" ,
135
+ experimentalStopGRPCServiceOnDefrag : "false" ,
136
+ expectedFeatures : map [featuregate.Feature ]bool {
137
+ features .StopGRPCServiceOnDefrag : false ,
138
+ features .DistributedTracing : false ,
139
+ },
140
+ },
141
+ {
142
+ name : "can set feature gate to true from feature gate flag" ,
143
+ serverFeatureGatesJSON : "StopGRPCServiceOnDefrag=true" ,
144
+ expectedFeatures : map [featuregate.Feature ]bool {
145
+ features .StopGRPCServiceOnDefrag : true ,
146
+ features .DistributedTracing : false ,
147
+ },
148
+ },
149
+ {
150
+ name : "can set feature gate to false from feature gate flag" ,
151
+ serverFeatureGatesJSON : "StopGRPCServiceOnDefrag=false" ,
152
+ expectedFeatures : map [featuregate.Feature ]bool {
153
+ features .StopGRPCServiceOnDefrag : false ,
154
+ features .DistributedTracing : false ,
155
+ },
128
156
},
129
157
}
130
158
for _ , tc := range testCases {
@@ -136,6 +164,13 @@ func TestConfigFileFeatureGates(t *testing.T) {
136
164
ServerFeatureGatesJSON : tc .serverFeatureGatesJSON ,
137
165
}
138
166
167
+ if tc .experimentalStopGRPCServiceOnDefrag != "" {
168
+ experimentalStopGRPCServiceOnDefrag , err := strconv .ParseBool (tc .experimentalStopGRPCServiceOnDefrag )
169
+ if err != nil {
170
+ t .Fatal (err )
171
+ }
172
+ yc .ExperimentalStopGRPCServiceOnDefrag = & experimentalStopGRPCServiceOnDefrag
173
+ }
139
174
b , err := yaml .Marshal (& yc )
140
175
if err != nil {
141
176
t .Fatal (err )
@@ -743,3 +778,87 @@ func TestUndefinedAutoCompactionModeValidate(t *testing.T) {
743
778
err := cfg .Validate ()
744
779
require .Error (t , err )
745
780
}
781
+
782
+ func TestSetFeatureGatesFromExperimentalFlags (t * testing.T ) {
783
+ testCases := []struct {
784
+ name string
785
+ featureGatesFlag string
786
+ experimentalStopGRPCServiceOnDefrag string
787
+ expectErr bool
788
+ expectedFeatures map [featuregate.Feature ]bool
789
+ }{
790
+ {
791
+ name : "default" ,
792
+ expectedFeatures : map [featuregate.Feature ]bool {
793
+ features .DistributedTracing : false ,
794
+ features .StopGRPCServiceOnDefrag : false ,
795
+ },
796
+ },
797
+ {
798
+ name : "cannot set experimental flag and feature gate to true at the same time" ,
799
+ featureGatesFlag : "StopGRPCServiceOnDefrag=true" ,
800
+ experimentalStopGRPCServiceOnDefrag : "true" ,
801
+ expectErr : true ,
802
+ },
803
+ {
804
+ name : "cannot set experimental flag and feature gate to false at the same time" ,
805
+ featureGatesFlag : "StopGRPCServiceOnDefrag=false" ,
806
+ experimentalStopGRPCServiceOnDefrag : "false" ,
807
+ expectErr : true ,
808
+ },
809
+ {
810
+ name : "cannot set experimental flag and feature gate to different values at the same time" ,
811
+ featureGatesFlag : "StopGRPCServiceOnDefrag=true" ,
812
+ experimentalStopGRPCServiceOnDefrag : "false" ,
813
+ expectErr : true ,
814
+ },
815
+ {
816
+ name : "can set experimental flag" ,
817
+ featureGatesFlag : "DistributedTracing=true" ,
818
+ experimentalStopGRPCServiceOnDefrag : "true" ,
819
+ expectedFeatures : map [featuregate.Feature ]bool {
820
+ features .DistributedTracing : true ,
821
+ features .StopGRPCServiceOnDefrag : true ,
822
+ },
823
+ },
824
+ {
825
+ name : "can set feature gate" ,
826
+ featureGatesFlag : "DistributedTracing=true,StopGRPCServiceOnDefrag=true" ,
827
+ expectedFeatures : map [featuregate.Feature ]bool {
828
+ features .DistributedTracing : true ,
829
+ features .StopGRPCServiceOnDefrag : true ,
830
+ },
831
+ },
832
+ }
833
+ for _ , tc := range testCases {
834
+ t .Run (tc .name , func (t * testing.T ) {
835
+ fg := features .NewDefaultServerFeatureGate ("test" , nil )
836
+ fg .(featuregate.MutableFeatureGate ).Set (tc .featureGatesFlag )
837
+ getExperimentalFlagVal := func (flagName string ) * bool {
838
+ if flagName != "experimental-stop-grpc-service-on-defrag" || tc .experimentalStopGRPCServiceOnDefrag == "" {
839
+ return nil
840
+ }
841
+ flagVal , err := strconv .ParseBool (tc .experimentalStopGRPCServiceOnDefrag )
842
+ if err != nil {
843
+ t .Fatal (err )
844
+ }
845
+ return & flagVal
846
+ }
847
+ err := SetFeatureGatesFromExperimentalFlags (fg , getExperimentalFlagVal , "feature-gates" , tc .featureGatesFlag )
848
+ if tc .expectErr {
849
+ if err == nil {
850
+ t .Fatal ("expect error" )
851
+ }
852
+ return
853
+ }
854
+ if err != nil {
855
+ t .Fatal (err )
856
+ }
857
+ for k , v := range tc .expectedFeatures {
858
+ if fg .Enabled (k ) != v {
859
+ t .Errorf ("expected feature gate %s=%v, got %v" , k , v , fg .Enabled (k ))
860
+ }
861
+ }
862
+ })
863
+ }
864
+ }
0 commit comments