feature_gate_test.go 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. package feature
  2. import (
  3. "flag"
  4. "fmt"
  5. "strings"
  6. "testing"
  7. )
  8. func TestFeatureGateOverride(t *testing.T) {
  9. const testAlphaGate Feature = "TestAlpha"
  10. const testBetaGate Feature = "TestBeta"
  11. // Don't parse the flag, assert defaults are used.
  12. var f Gate = NewGate()
  13. f.Add(map[Feature]Spec{
  14. testAlphaGate: {Default: false},
  15. testBetaGate: {Default: false},
  16. })
  17. f.Set("TestAlpha=true,TestBeta=true")
  18. if f.Enabled(testAlphaGate) != true {
  19. t.Errorf("Expected true")
  20. }
  21. if f.Enabled(testBetaGate) != true {
  22. t.Errorf("Expected true")
  23. }
  24. f.Set("TestAlpha=false")
  25. if f.Enabled(testAlphaGate) != false {
  26. t.Errorf("Expected false")
  27. }
  28. if f.Enabled(testBetaGate) != true {
  29. t.Errorf("Expected true")
  30. }
  31. }
  32. func TestFeatureGateFlagDefaults(t *testing.T) {
  33. // gates for testing
  34. const testAlphaGate Feature = "TestAlpha"
  35. const testBetaGate Feature = "TestBeta"
  36. // Don't parse the flag, assert defaults are used.
  37. var f Gate = NewGate()
  38. f.Add(map[Feature]Spec{
  39. testAlphaGate: {Default: false},
  40. testBetaGate: {Default: true},
  41. })
  42. if f.Enabled(testAlphaGate) != false {
  43. t.Errorf("Expected false")
  44. }
  45. if f.Enabled(testBetaGate) != true {
  46. t.Errorf("Expected true")
  47. }
  48. }
  49. func TestFeatureGateSetFromMap(t *testing.T) {
  50. // gates for testing
  51. const testAlphaGate Feature = "TestAlpha"
  52. const testBetaGate Feature = "TestBeta"
  53. tests := []struct {
  54. name string
  55. setmap map[string]bool
  56. expect map[Feature]bool
  57. setmapError string
  58. }{
  59. {
  60. name: "set TestAlpha and TestBeta true",
  61. setmap: map[string]bool{
  62. "TestAlpha": true,
  63. "TestBeta": true,
  64. },
  65. expect: map[Feature]bool{
  66. testAlphaGate: true,
  67. testBetaGate: true,
  68. },
  69. },
  70. {
  71. name: "set TestBeta true",
  72. setmap: map[string]bool{
  73. "TestBeta": true,
  74. },
  75. expect: map[Feature]bool{
  76. testAlphaGate: false,
  77. testBetaGate: true,
  78. },
  79. },
  80. {
  81. name: "set TestAlpha false",
  82. setmap: map[string]bool{
  83. "TestAlpha": false,
  84. },
  85. expect: map[Feature]bool{
  86. testAlphaGate: false,
  87. testBetaGate: false,
  88. },
  89. },
  90. {
  91. name: "set TestInvaild true",
  92. setmap: map[string]bool{
  93. "TestInvaild": true,
  94. },
  95. expect: map[Feature]bool{
  96. testAlphaGate: false,
  97. testBetaGate: false,
  98. },
  99. setmapError: "unrecognized key:",
  100. },
  101. }
  102. for i, test := range tests {
  103. t.Run(fmt.Sprintf("SetFromMap %s", test.name), func(t *testing.T) {
  104. f := NewGate()
  105. f.Add(map[Feature]Spec{
  106. testAlphaGate: {Default: false},
  107. testBetaGate: {Default: false},
  108. })
  109. err := f.SetFromMap(test.setmap)
  110. if test.setmapError != "" {
  111. if !strings.Contains(err.Error(), test.setmapError) {
  112. t.Errorf("%d: SetFromMap(%#v) Expected err:%v, Got err:%v", i, test.setmap, test.setmapError, err)
  113. }
  114. } else if err != nil {
  115. t.Errorf("%d: SetFromMap(%#v) Expected success, Got err:%v", i, test.setmap, err)
  116. }
  117. for k, v := range test.expect {
  118. if actual := f.Enabled(k); actual != v {
  119. t.Errorf("%d: SetFromMap(%#v) Expected %s=%v, Got %s=%v", i, test.setmap, k, v, k, actual)
  120. }
  121. }
  122. })
  123. }
  124. }
  125. func TestFeatureGateString(t *testing.T) {
  126. // gates for testing
  127. const testAlphaGate Feature = "TestAlpha"
  128. const testBetaGate Feature = "TestBeta"
  129. const testGAGate Feature = "TestGA"
  130. featuremap := map[Feature]Spec{
  131. testGAGate: {Default: true},
  132. testAlphaGate: {Default: false},
  133. testBetaGate: {Default: true},
  134. }
  135. tests := []struct {
  136. setmap map[string]bool
  137. expect string
  138. }{
  139. {
  140. setmap: map[string]bool{
  141. "TestAlpha": false,
  142. },
  143. expect: "TestAlpha=false",
  144. },
  145. {
  146. setmap: map[string]bool{
  147. "TestAlpha": false,
  148. "TestBeta": true,
  149. },
  150. expect: "TestAlpha=false,TestBeta=true",
  151. },
  152. {
  153. setmap: map[string]bool{
  154. "TestGA": true,
  155. "TestAlpha": false,
  156. "TestBeta": true,
  157. },
  158. expect: "TestAlpha=false,TestBeta=true,TestGA=true",
  159. },
  160. }
  161. for i, test := range tests {
  162. t.Run(fmt.Sprintf("SetFromMap %s", test.expect), func(t *testing.T) {
  163. f := NewGate()
  164. f.Add(featuremap)
  165. f.SetFromMap(test.setmap)
  166. result := f.String()
  167. if result != test.expect {
  168. t.Errorf("%d: SetFromMap(%#v) Expected %s, Got %s", i, test.setmap, test.expect, result)
  169. }
  170. })
  171. }
  172. }
  173. func TestFeatureGateFlag(t *testing.T) {
  174. // gates for testing
  175. const testAlphaGate Feature = "TestAlpha"
  176. const testBetaGate Feature = "TestBeta"
  177. tests := []struct {
  178. arg string
  179. expect map[Feature]bool
  180. parseError string
  181. }{
  182. {
  183. arg: "",
  184. expect: map[Feature]bool{
  185. testAlphaGate: false,
  186. testBetaGate: false,
  187. },
  188. },
  189. {
  190. arg: "fooBarBaz=maybeidk",
  191. expect: map[Feature]bool{
  192. testAlphaGate: false,
  193. testBetaGate: false,
  194. },
  195. parseError: "unrecognized key: fooBarBaz",
  196. },
  197. {
  198. arg: "TestAlpha=true",
  199. expect: map[Feature]bool{
  200. testAlphaGate: true,
  201. testBetaGate: false,
  202. },
  203. },
  204. {
  205. arg: "TestAlpha=true",
  206. expect: map[Feature]bool{
  207. testAlphaGate: true,
  208. testBetaGate: false,
  209. },
  210. },
  211. {
  212. arg: "TestAlpha=false",
  213. expect: map[Feature]bool{
  214. testAlphaGate: false,
  215. testBetaGate: false,
  216. },
  217. },
  218. {
  219. arg: "TestAlpha=false",
  220. expect: map[Feature]bool{
  221. testAlphaGate: false,
  222. testBetaGate: false,
  223. },
  224. },
  225. {
  226. arg: "TestBeta=true",
  227. expect: map[Feature]bool{
  228. testAlphaGate: false,
  229. testBetaGate: true,
  230. },
  231. },
  232. }
  233. for i, test := range tests {
  234. fs := flag.NewFlagSet("testfeaturegateflag", flag.ContinueOnError)
  235. f := NewGate()
  236. f.Add(map[Feature]Spec{
  237. testAlphaGate: {Default: false},
  238. testBetaGate: {Default: false},
  239. })
  240. f.AddFlag(fs)
  241. err := fs.Parse([]string{fmt.Sprintf("-%s=%s", flagName, test.arg)})
  242. if test.parseError != "" {
  243. if !strings.Contains(err.Error(), test.parseError) {
  244. t.Errorf("%d: Parse() Expected %v, Got %v", i, test.parseError, err)
  245. }
  246. } else if err != nil {
  247. t.Errorf("%d: Parse() Expected nil, Got %v", i, err)
  248. }
  249. for k, v := range test.expect {
  250. if actual := f.enabled.Load().(map[Feature]bool)[k]; actual != v {
  251. t.Errorf("%d: expected %s=%v, Got %v", i, k, v, actual)
  252. }
  253. }
  254. }
  255. }