github.com/influxdata/influxdb/v2@v2.7.6/kit/feature/override/override_test.go (about)

     1  package override
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	"github.com/influxdata/influxdb/v2/kit/feature"
     8  )
     9  
    10  func TestFlagger(t *testing.T) {
    11  
    12  	cases := []struct {
    13  		name           string
    14  		env            map[string]string
    15  		defaults       []feature.Flag
    16  		expected       map[string]interface{}
    17  		expectMakeErr  bool
    18  		expectFlagsErr bool
    19  		byKey          feature.ByKeyFn
    20  	}{
    21  		{
    22  			name: "enabled happy path filtering",
    23  			env: map[string]string{
    24  				"flag1": "new1",
    25  				"flag3": "new3",
    26  			},
    27  			defaults: []feature.Flag{
    28  				newFlag("flag0", "original0"),
    29  				newFlag("flag1", "original1"),
    30  				newFlag("flag2", "original2"),
    31  				newFlag("flag3", "original3"),
    32  				newFlag("flag4", "original4"),
    33  			},
    34  			byKey: newByKey(map[string]feature.Flag{
    35  				"flag0": newFlag("flag0", "original0"),
    36  				"flag1": newFlag("flag1", "original1"),
    37  				"flag2": newFlag("flag2", "original2"),
    38  				"flag3": newFlag("flag3", "original3"),
    39  				"flag4": newFlag("flag4", "original4"),
    40  			}),
    41  			expected: map[string]interface{}{
    42  				"flag0": "original0",
    43  				"flag1": "new1",
    44  				"flag2": "original2",
    45  				"flag3": "new3",
    46  				"flag4": "original4",
    47  			},
    48  		},
    49  		{
    50  			name: "enabled happy path types",
    51  			env: map[string]string{
    52  				"intflag":   "43",
    53  				"floatflag": "43.43",
    54  				"boolflag":  "true",
    55  			},
    56  			defaults: []feature.Flag{
    57  				newFlag("intflag", 42),
    58  				newFlag("floatflag", 42.42),
    59  				newFlag("boolflag", false),
    60  			},
    61  			byKey: newByKey(map[string]feature.Flag{
    62  				"intflag":   newFlag("intflag", 42),
    63  				"floatflag": newFlag("floatflag", 43.43),
    64  				"boolflag":  newFlag("boolflag", false),
    65  			}),
    66  			expected: map[string]interface{}{
    67  				"intflag":   43,
    68  				"floatflag": 43.43,
    69  				"boolflag":  true,
    70  			},
    71  		},
    72  		{
    73  			name: "type coerce error",
    74  			env: map[string]string{
    75  				"key": "not_an_int",
    76  			},
    77  			defaults: []feature.Flag{
    78  				newFlag("key", 42),
    79  			},
    80  			byKey: newByKey(map[string]feature.Flag{
    81  				"key": newFlag("key", 42),
    82  			}),
    83  			expectFlagsErr: true,
    84  		},
    85  		{
    86  			name: "typed base flags",
    87  			env: map[string]string{
    88  				"flag1": "411",
    89  				"flag2": "new2",
    90  				"flag3": "true",
    91  			},
    92  			defaults: []feature.Flag{
    93  				newBaseFlag("flag0", "original0"),
    94  				newBaseFlag("flag1", 41),
    95  				newBaseFlag("flag2", "original2"),
    96  				newBaseFlag("flag3", false),
    97  				newBaseFlag("flag4", "original4"),
    98  			},
    99  			byKey: newByKey(map[string]feature.Flag{
   100  				"flag0": newFlag("flag0", "original0"),
   101  				"flag1": newFlag("flag1", 41),
   102  				"flag2": newFlag("flag2", "original2"),
   103  				"flag3": newFlag("flag3", false),
   104  				"flag4": newFlag("flag4", "original4"),
   105  			}),
   106  			expected: map[string]interface{}{
   107  				"flag0": "original0",
   108  				"flag1": 411,
   109  				"flag2": "new2",
   110  				"flag3": true,
   111  				"flag4": "original4",
   112  			},
   113  		},
   114  		{
   115  			name: "override for non-existent flag",
   116  			env: map[string]string{
   117  				"dne": "foobar",
   118  			},
   119  			defaults: []feature.Flag{
   120  				newBaseFlag("key", "value"),
   121  			},
   122  			byKey: newByKey(map[string]feature.Flag{
   123  				"key": newFlag("key", "value"),
   124  			}),
   125  			expectMakeErr: true,
   126  		},
   127  	}
   128  
   129  	for _, test := range cases {
   130  		t.Run(test.name, func(t *testing.T) {
   131  			subject, err := Make(test.env, test.byKey)
   132  			if err != nil {
   133  				if test.expectMakeErr {
   134  					return
   135  				}
   136  				t.Fatalf("unexpected error making Flagger: %v", err)
   137  			}
   138  
   139  			computed, err := subject.Flags(context.Background(), test.defaults...)
   140  			if err != nil {
   141  				if test.expectFlagsErr {
   142  					return
   143  				}
   144  				t.Fatalf("unexpected error calling Flags: %v", err)
   145  			}
   146  
   147  			if len(computed) != len(test.expected) {
   148  				t.Fatalf("incorrect number of flags computed: expected %d, got %d", len(test.expected), len(computed))
   149  			}
   150  
   151  			// check for extra or incorrect keys
   152  			for k, v := range computed {
   153  				if xv, found := test.expected[k]; !found {
   154  					t.Errorf("unexpected key %s", k)
   155  				} else if v != xv {
   156  					t.Errorf("incorrect value for key %s: expected %v [%T], got %v [%T]", k, xv, xv, v, v)
   157  				}
   158  			}
   159  
   160  			// check for missing keys
   161  			for k := range test.expected {
   162  				if _, found := computed[k]; !found {
   163  					t.Errorf("missing expected key %s", k)
   164  				}
   165  			}
   166  		})
   167  	}
   168  }
   169  
   170  func newFlag(key string, defaultValue interface{}) feature.Flag {
   171  	return feature.MakeFlag(key, key, "", defaultValue, feature.Temporary, false)
   172  }
   173  
   174  func newBaseFlag(key string, defaultValue interface{}) feature.Base {
   175  	return feature.MakeBase(key, key, "", defaultValue, feature.Temporary, false)
   176  }
   177  
   178  func newByKey(m map[string]feature.Flag) feature.ByKeyFn {
   179  	return func(k string) (feature.Flag, bool) {
   180  		v, found := m[k]
   181  		return v, found
   182  	}
   183  }