istio.io/istio@v0.0.0-20240520182934-d79c90f27776/pkg/env/var_test.go (about)

     1  // Copyright 2019 Istio Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // Package env makes it possible to track use of environment variables within process
    16  // in order to generate documentation for these uses.
    17  package env
    18  
    19  import (
    20  	"os"
    21  	"testing"
    22  	"time"
    23  )
    24  
    25  const testVar = "TESTXYZ"
    26  
    27  func reset() {
    28  	_ = os.Unsetenv(testVar)
    29  	mutex.Lock()
    30  	allVars = make(map[string]Var)
    31  	mutex.Unlock()
    32  }
    33  
    34  func TestString(t *testing.T) {
    35  	reset()
    36  
    37  	ev := RegisterStringVar(testVar, "123", "")
    38  	v, present := ev.Lookup()
    39  	if v != "123" {
    40  		t.Errorf("Expected 123, got %s", v)
    41  	}
    42  	if present {
    43  		t.Errorf("Expected not present")
    44  	}
    45  
    46  	v = ev.Get()
    47  	if v != "123" {
    48  		t.Errorf("Expected 123, got %s", v)
    49  	}
    50  
    51  	_ = os.Setenv(testVar, "ABC")
    52  
    53  	ev = RegisterStringVar(testVar, "123", "")
    54  	v, present = ev.Lookup()
    55  	if v != "ABC" {
    56  		t.Errorf("Expected ABC, got %s", v)
    57  	}
    58  	if !present {
    59  		t.Errorf("Expected present")
    60  	}
    61  
    62  	v = ev.Get()
    63  	if v != "ABC" {
    64  		t.Errorf("Expected ABC, got %s", v)
    65  	}
    66  }
    67  
    68  func runTest[T Parseable](t *testing.T, name string, v1 T, s2 string, v2 T) {
    69  	t.Run(name, func(t *testing.T) {
    70  		reset()
    71  		ev := Register(testVar, v1, "")
    72  		v, present := ev.Lookup()
    73  		if v != v1 {
    74  			t.Errorf("Expected %v, got %v", v1, v)
    75  		}
    76  		if present {
    77  			t.Errorf("Expected not present")
    78  		}
    79  
    80  		v = ev.Get()
    81  		if v != v1 {
    82  			t.Errorf("Expected %v, got %v", v1, v)
    83  		}
    84  
    85  		_ = os.Setenv(testVar, "XXX")
    86  
    87  		ev = Register(testVar, v1, "")
    88  		v, present = ev.Lookup()
    89  		if v != v1 {
    90  			t.Errorf("Expected %v, got %v", v1, v)
    91  		}
    92  		if !present {
    93  			t.Errorf("Expected present")
    94  		}
    95  
    96  		v = ev.Get()
    97  		if v != v1 {
    98  			t.Errorf("Expected %v, got %v", v1, v)
    99  		}
   100  
   101  		_ = os.Setenv(testVar, s2)
   102  
   103  		ev = Register(testVar, v1, "")
   104  		v, present = ev.Lookup()
   105  		if v != v2 {
   106  			t.Errorf("Expected %v, got %v", v2, v)
   107  		}
   108  		if !present {
   109  			t.Errorf("Expected present")
   110  		}
   111  
   112  		v = ev.Get()
   113  		if v != v2 {
   114  			t.Errorf("Expected %v, got %v", v2, v)
   115  		}
   116  	})
   117  }
   118  
   119  func TestGeneric(t *testing.T) {
   120  	type test struct {
   121  		A string `json:"a"`
   122  	}
   123  	runTest(t, "int", 123, "789", 789)
   124  	runTest(t, "int32", int32(123), "789", 789)
   125  	runTest(t, "bool", false, "true", true)
   126  	runTest(t, "duration", time.Second, "1m", time.Minute)
   127  	runTest(t, "float64", float64(1.5), "2.5", float64(2.5))
   128  	runTest(t, "float32", float32(1.5), "2.5", float32(2.5))
   129  	runTest(t, "complex", test{A: "2"}, `{"a":"3"}`, test{A: "3"})
   130  }
   131  
   132  func TestInt(t *testing.T) {
   133  	reset()
   134  
   135  	ev := RegisterIntVar(testVar, 123, "")
   136  	v, present := ev.Lookup()
   137  	if v != 123 {
   138  		t.Errorf("Expected 123, got %v", v)
   139  	}
   140  	if present {
   141  		t.Errorf("Expected not present")
   142  	}
   143  
   144  	v = ev.Get()
   145  	if v != 123 {
   146  		t.Errorf("Expected 123, got %v", v)
   147  	}
   148  
   149  	_ = os.Setenv(testVar, "XXX")
   150  
   151  	ev = RegisterIntVar(testVar, 123, "")
   152  	v, present = ev.Lookup()
   153  	if v != 123 {
   154  		t.Errorf("Expected 123, got %v", v)
   155  	}
   156  	if !present {
   157  		t.Errorf("Expected present")
   158  	}
   159  
   160  	v = ev.Get()
   161  	if v != 123 {
   162  		t.Errorf("Expected 123, got %v", v)
   163  	}
   164  
   165  	_ = os.Setenv(testVar, "789")
   166  
   167  	ev = RegisterIntVar(testVar, 123, "")
   168  	v, present = ev.Lookup()
   169  	if v != 789 {
   170  		t.Errorf("Expected 789, got %v", v)
   171  	}
   172  	if !present {
   173  		t.Errorf("Expected present")
   174  	}
   175  
   176  	v = ev.Get()
   177  	if v != 789 {
   178  		t.Errorf("Expected 789, got %v", v)
   179  	}
   180  }
   181  
   182  func TestBool(t *testing.T) {
   183  	reset()
   184  
   185  	ev := RegisterBoolVar(testVar, true, "")
   186  	v, present := ev.Lookup()
   187  	if !v {
   188  		t.Errorf("Expected true, got %v", v)
   189  	}
   190  	if present {
   191  		t.Errorf("Expected not present")
   192  	}
   193  
   194  	v = ev.Get()
   195  	if !v {
   196  		t.Errorf("Expected true, got %v", v)
   197  	}
   198  
   199  	_ = os.Setenv(testVar, "XXX")
   200  
   201  	ev = RegisterBoolVar(testVar, true, "")
   202  	v, present = ev.Lookup()
   203  	if !v {
   204  		t.Errorf("Expected true, got %v", v)
   205  	}
   206  	if !present {
   207  		t.Errorf("Expected present")
   208  	}
   209  
   210  	v = ev.Get()
   211  	if !v {
   212  		t.Errorf("Expected true, got %v", v)
   213  	}
   214  
   215  	_ = os.Setenv(testVar, "true")
   216  
   217  	ev = RegisterBoolVar(testVar, false, "")
   218  	v, present = ev.Lookup()
   219  	if !v {
   220  		t.Errorf("Expected true, got %v", v)
   221  	}
   222  	if !present {
   223  		t.Errorf("Expected present")
   224  	}
   225  
   226  	v = ev.Get()
   227  	if !v {
   228  		t.Errorf("Expected true, got %v", v)
   229  	}
   230  }
   231  
   232  func TestFloat(t *testing.T) {
   233  	reset()
   234  
   235  	ev := RegisterFloatVar(testVar, 123.0, "")
   236  	v, present := ev.Lookup()
   237  	if v != 123.0 {
   238  		t.Errorf("Expected 123.0, got %v", v)
   239  	}
   240  	if present {
   241  		t.Errorf("Expected not present")
   242  	}
   243  
   244  	v = ev.Get()
   245  	if v != 123.0 {
   246  		t.Errorf("Expected 123.0, got %v", v)
   247  	}
   248  
   249  	_ = os.Setenv(testVar, "XXX")
   250  
   251  	ev = RegisterFloatVar(testVar, 123.0, "")
   252  	v, present = ev.Lookup()
   253  	if v != 123.0 {
   254  		t.Errorf("Expected 123.0, got %v", v)
   255  	}
   256  	if !present {
   257  		t.Errorf("Expected present")
   258  	}
   259  
   260  	v = ev.Get()
   261  	if v != 123.0 {
   262  		t.Errorf("Expected 123.0, got %v", v)
   263  	}
   264  
   265  	_ = os.Setenv(testVar, "789")
   266  
   267  	ev = RegisterFloatVar(testVar, 123.0, "")
   268  	v, present = ev.Lookup()
   269  	if v != 789 {
   270  		t.Errorf("Expected 789.0, got %v", v)
   271  	}
   272  	if !present {
   273  		t.Errorf("Expected present")
   274  	}
   275  
   276  	v = ev.Get()
   277  	if v != 789 {
   278  		t.Errorf("Expected 789.0, got %v", v)
   279  	}
   280  }
   281  
   282  func TestDuration(t *testing.T) {
   283  	reset()
   284  
   285  	ev := RegisterDurationVar(testVar, 123*time.Second, "")
   286  	v, present := ev.Lookup()
   287  	if v != 123*time.Second {
   288  		t.Errorf("Expected 123 seconds, got %v", v)
   289  	}
   290  	if present {
   291  		t.Errorf("Expected not present")
   292  	}
   293  
   294  	v = ev.Get()
   295  	if v != 123*time.Second {
   296  		t.Errorf("Expected 123 seconds, got %v", v)
   297  	}
   298  
   299  	_ = os.Setenv(testVar, "XXX")
   300  
   301  	ev = RegisterDurationVar(testVar, 123*time.Second, "")
   302  	v, present = ev.Lookup()
   303  	if v != 123*time.Second {
   304  		t.Errorf("Expected 123 seconds, got %v", v)
   305  	}
   306  	if !present {
   307  		t.Errorf("Expected present")
   308  	}
   309  
   310  	v = ev.Get()
   311  	if v != 123*time.Second {
   312  		t.Errorf("Expected 123 seconds, got %v", v)
   313  	}
   314  
   315  	_ = os.Setenv(testVar, "789s")
   316  
   317  	ev = RegisterDurationVar(testVar, 123*time.Second, "")
   318  	v, present = ev.Lookup()
   319  	if v != 789*time.Second {
   320  		t.Errorf("Expected 789 seconds, got %v", v)
   321  	}
   322  	if !present {
   323  		t.Errorf("Expected present")
   324  	}
   325  
   326  	v = ev.Get()
   327  	if v != 789*time.Second {
   328  		t.Errorf("Expected 789 seconds, got %v", v)
   329  	}
   330  }
   331  
   332  func TestDesc(t *testing.T) {
   333  	reset()
   334  
   335  	_ = RegisterDurationVar(testVar+"5", 123*time.Second, "A duration")
   336  	_ = RegisterStringVar(testVar+"1", "123", "A string")
   337  	_ = RegisterIntVar(testVar+"2", 456, "An int")
   338  	_ = RegisterBoolVar(testVar+"3", true, "A bool")
   339  	_ = RegisterFloatVar(testVar+"4", 789.0, "A float")
   340  
   341  	vars := VarDescriptions()
   342  	if vars[0].Name != "TESTXYZ1" {
   343  		t.Errorf("Expecting TESTXYZ1, got %s", vars[0].Name)
   344  	}
   345  	if vars[0].Description != "A string" {
   346  		t.Errorf("Expected 'A string', got '%s'", vars[0].Description)
   347  	}
   348  
   349  	if vars[1].Name != "TESTXYZ2" {
   350  		t.Errorf("Expecting TESTXYZ2, got %s", vars[0].Name)
   351  	}
   352  	if vars[1].Description != "An int" {
   353  		t.Errorf("Expected 'An int', got '%s'", vars[0].Description)
   354  	}
   355  
   356  	if vars[2].Name != "TESTXYZ3" {
   357  		t.Errorf("Expecting TESTXYZ3, got %s", vars[0].Name)
   358  	}
   359  	if vars[2].Description != "A bool" {
   360  		t.Errorf("Expected 'A bool', got '%s'", vars[0].Description)
   361  	}
   362  
   363  	if vars[3].Name != "TESTXYZ4" {
   364  		t.Errorf("Expecting TESTXYZ4, got %s", vars[0].Name)
   365  	}
   366  	if vars[3].Description != "A float" {
   367  		t.Errorf("Expected 'A float', got '%s'", vars[0].Description)
   368  	}
   369  
   370  	if vars[4].Name != "TESTXYZ5" {
   371  		t.Errorf("Expecting TESTXYZ5, got %s", vars[0].Name)
   372  	}
   373  	if vars[4].Description != "A duration" {
   374  		t.Errorf("Expected 'A duration', got '%s'", vars[0].Description)
   375  	}
   376  }
   377  
   378  func TestDupes(t *testing.T) {
   379  	// make sure var without a description doesn't overwrite one with
   380  	reset()
   381  	_ = RegisterStringVar(testVar, "123", "XYZ")
   382  	v := RegisterStringVar(testVar, "123", "")
   383  	if v.Description != "XYZ" {
   384  		t.Errorf("Expected 'XYZ', got '%s'", v.Description)
   385  	}
   386  
   387  	// make sure var without a description doesn't overwrite one with
   388  	reset()
   389  	_ = RegisterStringVar(testVar, "123", "")
   390  	v = RegisterStringVar(testVar, "123", "XYZ")
   391  	if v.Description != "XYZ" {
   392  		t.Errorf("Expected 'XYZ', got '%s'", v.Description)
   393  	}
   394  }