github.com/DerekStrickland/consul@v1.4.5/command/connect/envoy/envoy_test.go (about) 1 package envoy 2 3 import ( 4 "flag" 5 "io/ioutil" 6 "os" 7 "path/filepath" 8 "strings" 9 "testing" 10 11 "github.com/hashicorp/consul/agent/xds" 12 "github.com/mitchellh/cli" 13 "github.com/stretchr/testify/require" 14 ) 15 16 var update = flag.Bool("update", false, "update golden files") 17 18 func TestCatalogCommand_noTabs(t *testing.T) { 19 t.Parallel() 20 if strings.ContainsRune(New(nil).Help(), '\t') { 21 t.Fatal("help has tabs") 22 } 23 } 24 25 // testSetAndResetEnv sets the env vars passed as KEY=value strings in the 26 // current ENV and returns a func() that will undo it's work at the end of the 27 // test for use with defer. 28 func testSetAndResetEnv(t *testing.T, env []string) func() { 29 old := make(map[string]*string) 30 for _, e := range env { 31 pair := strings.SplitN(e, "=", 2) 32 current := os.Getenv(pair[0]) 33 if current != "" { 34 old[pair[0]] = ¤t 35 } else { 36 // save it as a nil so we know to remove again 37 old[pair[0]] = nil 38 } 39 os.Setenv(pair[0], pair[1]) 40 } 41 // Return a func that will reset to old values 42 return func() { 43 for k, v := range old { 44 if v == nil { 45 os.Unsetenv(k) 46 } else { 47 os.Setenv(k, *v) 48 } 49 } 50 } 51 } 52 53 // This tests the args we use to generate the template directly because they 54 // encapsulate all the argument and default handling code which is where most of 55 // the logic is. We also allow generating golden files but only for cases that 56 // pass the test of having their template args generated as expected. 57 func TestGenerateConfig(t *testing.T) { 58 cases := []struct { 59 Name string 60 Flags []string 61 Env []string 62 WantArgs templateArgs 63 WantErr string 64 }{ 65 { 66 Name: "no-args", 67 Flags: []string{}, 68 Env: []string{}, 69 WantErr: "No proxy ID specified", 70 }, 71 { 72 Name: "defaults", 73 Flags: []string{"-proxy-id", "test-proxy"}, 74 Env: []string{}, 75 WantArgs: templateArgs{ 76 ProxyCluster: "test-proxy", 77 ProxyID: "test-proxy", 78 AgentAddress: "127.0.0.1", 79 AgentPort: "8502", // Note this is the gRPC port 80 AdminBindAddress: "127.0.0.1", 81 AdminBindPort: "19000", 82 LocalAgentClusterName: xds.LocalAgentClusterName, 83 }, 84 }, 85 { 86 Name: "grpc-addr-flag", 87 Flags: []string{"-proxy-id", "test-proxy", 88 "-grpc-addr", "localhost:9999"}, 89 Env: []string{}, 90 WantArgs: templateArgs{ 91 ProxyCluster: "test-proxy", 92 ProxyID: "test-proxy", 93 // Should resolve IP, note this might not resolve the same way 94 // everywhere which might make this test brittle but not sure what else 95 // to do. 96 AgentAddress: "127.0.0.1", 97 AgentPort: "9999", 98 AdminBindAddress: "127.0.0.1", 99 AdminBindPort: "19000", 100 LocalAgentClusterName: xds.LocalAgentClusterName, 101 }, 102 }, 103 { 104 Name: "grpc-addr-env", 105 Flags: []string{"-proxy-id", "test-proxy"}, 106 Env: []string{ 107 "CONSUL_GRPC_ADDR=localhost:9999", 108 }, 109 WantArgs: templateArgs{ 110 ProxyCluster: "test-proxy", 111 ProxyID: "test-proxy", 112 // Should resolve IP, note this might not resolve the same way 113 // everywhere which might make this test brittle but not sure what else 114 // to do. 115 AgentAddress: "127.0.0.1", 116 AgentPort: "9999", 117 AdminBindAddress: "127.0.0.1", 118 AdminBindPort: "19000", 119 LocalAgentClusterName: xds.LocalAgentClusterName, 120 }, 121 }, 122 // TODO(banks): all the flags/env manipulation cases 123 } 124 125 for _, tc := range cases { 126 t.Run(tc.Name, func(t *testing.T) { 127 require := require.New(t) 128 129 ui := cli.NewMockUi() 130 c := New(ui) 131 132 defer testSetAndResetEnv(t, tc.Env)() 133 134 // Run the command 135 args := append([]string{"-bootstrap"}, tc.Flags...) 136 code := c.Run(args) 137 if tc.WantErr == "" { 138 require.Equal(0, code, ui.ErrorWriter.String()) 139 } else { 140 require.Equal(1, code, ui.ErrorWriter.String()) 141 require.Contains(ui.ErrorWriter.String(), tc.WantErr) 142 return 143 } 144 145 // Verify we handled the env and flags right first to get correct template 146 // args. 147 got, err := c.templateArgs() 148 require.NoError(err) // Error cases should have returned above 149 require.Equal(&tc.WantArgs, got) 150 151 // Actual template output goes to stdout direct to avoid prefix in UI, so 152 // generate it again here to assert on. 153 actual, err := c.generateConfig() 154 require.NoError(err) 155 156 // If we got the arg handling write, verify output 157 golden := filepath.Join("testdata", tc.Name+".golden") 158 if *update { 159 ioutil.WriteFile(golden, actual, 0644) 160 } 161 162 expected, err := ioutil.ReadFile(golden) 163 require.NoError(err) 164 require.Equal(string(expected), string(actual)) 165 }) 166 } 167 }