2023-03-28 19:12:30 +00:00
|
|
|
// Copyright (c) HashiCorp, Inc.
|
2023-08-11 13:12:13 +00:00
|
|
|
// SPDX-License-Identifier: BUSL-1.1
|
2023-03-28 19:12:30 +00:00
|
|
|
|
2018-05-19 18:04:47 +00:00
|
|
|
package proxy
|
|
|
|
|
|
|
|
import (
|
2018-10-03 19:37:53 +00:00
|
|
|
"strings"
|
2018-05-19 18:04:47 +00:00
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/hashicorp/consul/agent"
|
|
|
|
"github.com/hashicorp/consul/connect/proxy"
|
|
|
|
"github.com/mitchellh/cli"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestCommandConfigWatcher(t *testing.T) {
|
2020-12-07 18:42:55 +00:00
|
|
|
if testing.Short() {
|
|
|
|
t.Skip("too slow for testing.Short")
|
|
|
|
}
|
|
|
|
|
2018-05-19 18:04:47 +00:00
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
cases := []struct {
|
2018-09-27 14:00:51 +00:00
|
|
|
Name string
|
|
|
|
Flags []string
|
|
|
|
Test func(*testing.T, *proxy.Config)
|
|
|
|
WantErr string
|
2018-05-19 18:04:47 +00:00
|
|
|
}{
|
|
|
|
{
|
2018-09-27 14:00:51 +00:00
|
|
|
Name: "-service flag only",
|
|
|
|
Flags: []string{"-service", "web"},
|
|
|
|
Test: func(t *testing.T, cfg *proxy.Config) {
|
2018-05-19 18:04:47 +00:00
|
|
|
require.Equal(t, 0, cfg.PublicListener.BindPort)
|
|
|
|
require.Len(t, cfg.Upstreams, 0)
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
2018-09-27 14:00:51 +00:00
|
|
|
Name: "-service flag with upstreams",
|
|
|
|
Flags: []string{
|
2018-05-19 18:04:47 +00:00
|
|
|
"-service", "web",
|
|
|
|
"-upstream", "db:1234",
|
|
|
|
"-upstream", "db2:2345",
|
|
|
|
},
|
2018-09-27 14:00:51 +00:00
|
|
|
Test: func(t *testing.T, cfg *proxy.Config) {
|
2018-05-19 18:04:47 +00:00
|
|
|
require.Equal(t, 0, cfg.PublicListener.BindPort)
|
|
|
|
require.Len(t, cfg.Upstreams, 2)
|
|
|
|
require.Equal(t, 1234, cfg.Upstreams[0].LocalBindPort)
|
|
|
|
require.Equal(t, 2345, cfg.Upstreams[1].LocalBindPort)
|
|
|
|
},
|
|
|
|
},
|
2018-05-19 18:20:20 +00:00
|
|
|
|
|
|
|
{
|
2018-09-27 14:00:51 +00:00
|
|
|
Name: "-service flag with -service-addr",
|
|
|
|
Flags: []string{"-service", "web"},
|
|
|
|
Test: func(t *testing.T, cfg *proxy.Config) {
|
2018-05-19 18:20:20 +00:00
|
|
|
// -service-addr has no affect since -listen isn't set
|
|
|
|
require.Equal(t, 0, cfg.PublicListener.BindPort)
|
|
|
|
require.Len(t, cfg.Upstreams, 0)
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
2018-09-27 14:00:51 +00:00
|
|
|
Name: "-service, -service-addr, -listen",
|
|
|
|
Flags: []string{
|
2018-05-19 18:20:20 +00:00
|
|
|
"-service", "web",
|
|
|
|
"-service-addr", "127.0.0.1:1234",
|
|
|
|
"-listen", ":4567",
|
|
|
|
},
|
2018-09-27 14:00:51 +00:00
|
|
|
Test: func(t *testing.T, cfg *proxy.Config) {
|
2018-05-19 18:20:20 +00:00
|
|
|
require.Len(t, cfg.Upstreams, 0)
|
|
|
|
|
|
|
|
require.Equal(t, "", cfg.PublicListener.BindAddress)
|
|
|
|
require.Equal(t, 4567, cfg.PublicListener.BindPort)
|
|
|
|
require.Equal(t, "127.0.0.1:1234", cfg.PublicListener.LocalServiceAddress)
|
|
|
|
},
|
|
|
|
},
|
2018-09-27 14:00:51 +00:00
|
|
|
|
|
|
|
{
|
|
|
|
Name: "-sidecar-for, no sidecar",
|
|
|
|
Flags: []string{
|
|
|
|
"-sidecar-for", "no-sidecar",
|
|
|
|
},
|
|
|
|
WantErr: "No sidecar proxy registered",
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
Name: "-sidecar-for, multiple sidecars",
|
|
|
|
Flags: []string{
|
|
|
|
"-sidecar-for", "two-sidecars",
|
|
|
|
},
|
|
|
|
// Order is non-deterministic so don't assert the list of proxy IDs here
|
2018-10-09 16:57:26 +00:00
|
|
|
WantErr: `More than one sidecar proxy registered for two-sidecars.
|
2018-09-27 14:00:51 +00:00
|
|
|
Start proxy with -proxy-id and one of the following IDs: `,
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
Name: "-sidecar-for, non-existent",
|
|
|
|
Flags: []string{
|
|
|
|
"-sidecar-for", "foo",
|
|
|
|
},
|
|
|
|
WantErr: "No sidecar proxy registered",
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
Name: "-sidecar-for, one sidecar",
|
|
|
|
Flags: []string{
|
|
|
|
"-sidecar-for", "one-sidecar",
|
|
|
|
},
|
|
|
|
Test: func(t *testing.T, cfg *proxy.Config) {
|
|
|
|
// Sanity check we got the right instance.
|
|
|
|
require.Equal(t, 9999, cfg.PublicListener.BindPort)
|
|
|
|
},
|
|
|
|
},
|
2022-08-05 17:45:24 +00:00
|
|
|
|
|
|
|
{
|
|
|
|
Name: "-sidecar-for, one sidecar case-insensitive",
|
|
|
|
Flags: []string{
|
|
|
|
"-sidecar-for", "One-SideCar",
|
|
|
|
},
|
|
|
|
Test: func(t *testing.T, cfg *proxy.Config) {
|
|
|
|
// Sanity check we got the right instance.
|
|
|
|
require.Equal(t, 9999, cfg.PublicListener.BindPort)
|
|
|
|
},
|
|
|
|
},
|
2018-05-19 18:04:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range cases {
|
|
|
|
t.Run(tc.Name, func(t *testing.T) {
|
|
|
|
|
2018-10-09 09:57:26 +00:00
|
|
|
// Register a few services with 0, 1 and 2 sidecars
|
2020-03-31 19:59:56 +00:00
|
|
|
a := agent.NewTestAgent(t, `
|
2018-09-27 14:00:51 +00:00
|
|
|
services {
|
|
|
|
name = "no-sidecar"
|
|
|
|
port = 1111
|
|
|
|
}
|
|
|
|
services {
|
|
|
|
name = "one-sidecar"
|
|
|
|
port = 2222
|
|
|
|
connect {
|
|
|
|
sidecar_service {
|
|
|
|
port = 9999
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
services {
|
|
|
|
name = "two-sidecars"
|
|
|
|
port = 3333
|
|
|
|
connect {
|
|
|
|
sidecar_service {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
services {
|
|
|
|
kind = "connect-proxy"
|
|
|
|
name = "other-sidecar-for-two-sidecars"
|
|
|
|
port = 4444
|
|
|
|
proxy {
|
|
|
|
destination_service_id = "two-sidecars"
|
|
|
|
destination_service_name = "two-sidecars"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
`)
|
2018-05-19 18:04:47 +00:00
|
|
|
defer a.Shutdown()
|
|
|
|
client := a.Client()
|
|
|
|
|
|
|
|
ui := cli.NewMockUi()
|
|
|
|
c := New(ui, make(chan struct{}))
|
|
|
|
c.testNoStart = true
|
|
|
|
|
2018-09-27 14:00:51 +00:00
|
|
|
// Run the command
|
2018-05-19 18:04:47 +00:00
|
|
|
code := c.Run(append([]string{
|
|
|
|
"-http-addr=" + a.HTTPAddr(),
|
|
|
|
}, tc.Flags...))
|
2018-09-27 14:00:51 +00:00
|
|
|
if tc.WantErr == "" {
|
bulk rewrite using this script
set -euo pipefail
unset CDPATH
cd "$(dirname "$0")"
for f in $(git grep '\brequire := require\.New(' | cut -d':' -f1 | sort -u); do
echo "=== require: $f ==="
sed -i '/require := require.New(t)/d' $f
# require.XXX(blah) but not require.XXX(tblah) or require.XXX(rblah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\([^tr]\)/require.\1(t,\2/g' $f
# require.XXX(tblah) but not require.XXX(t, blah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\(t[^,]\)/require.\1(t,\2/g' $f
# require.XXX(rblah) but not require.XXX(r, blah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\(r[^,]\)/require.\1(t,\2/g' $f
gofmt -s -w $f
done
for f in $(git grep '\bassert := assert\.New(' | cut -d':' -f1 | sort -u); do
echo "=== assert: $f ==="
sed -i '/assert := assert.New(t)/d' $f
# assert.XXX(blah) but not assert.XXX(tblah) or assert.XXX(rblah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\([^tr]\)/assert.\1(t,\2/g' $f
# assert.XXX(tblah) but not assert.XXX(t, blah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\(t[^,]\)/assert.\1(t,\2/g' $f
# assert.XXX(rblah) but not assert.XXX(r, blah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\(r[^,]\)/assert.\1(t,\2/g' $f
gofmt -s -w $f
done
2022-01-20 16:46:23 +00:00
|
|
|
require.Equal(t, 0, code, ui.ErrorWriter.String())
|
2018-09-27 14:00:51 +00:00
|
|
|
} else {
|
bulk rewrite using this script
set -euo pipefail
unset CDPATH
cd "$(dirname "$0")"
for f in $(git grep '\brequire := require\.New(' | cut -d':' -f1 | sort -u); do
echo "=== require: $f ==="
sed -i '/require := require.New(t)/d' $f
# require.XXX(blah) but not require.XXX(tblah) or require.XXX(rblah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\([^tr]\)/require.\1(t,\2/g' $f
# require.XXX(tblah) but not require.XXX(t, blah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\(t[^,]\)/require.\1(t,\2/g' $f
# require.XXX(rblah) but not require.XXX(r, blah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\(r[^,]\)/require.\1(t,\2/g' $f
gofmt -s -w $f
done
for f in $(git grep '\bassert := assert\.New(' | cut -d':' -f1 | sort -u); do
echo "=== assert: $f ==="
sed -i '/assert := assert.New(t)/d' $f
# assert.XXX(blah) but not assert.XXX(tblah) or assert.XXX(rblah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\([^tr]\)/assert.\1(t,\2/g' $f
# assert.XXX(tblah) but not assert.XXX(t, blah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\(t[^,]\)/assert.\1(t,\2/g' $f
# assert.XXX(rblah) but not assert.XXX(r, blah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\(r[^,]\)/assert.\1(t,\2/g' $f
gofmt -s -w $f
done
2022-01-20 16:46:23 +00:00
|
|
|
require.Equal(t, 1, code, ui.ErrorWriter.String())
|
|
|
|
require.Contains(t, ui.ErrorWriter.String(), tc.WantErr)
|
2018-09-27 14:00:51 +00:00
|
|
|
return
|
|
|
|
}
|
2018-05-19 18:04:47 +00:00
|
|
|
|
|
|
|
// Get the configuration watcher
|
|
|
|
cw, err := c.configWatcher(client)
|
bulk rewrite using this script
set -euo pipefail
unset CDPATH
cd "$(dirname "$0")"
for f in $(git grep '\brequire := require\.New(' | cut -d':' -f1 | sort -u); do
echo "=== require: $f ==="
sed -i '/require := require.New(t)/d' $f
# require.XXX(blah) but not require.XXX(tblah) or require.XXX(rblah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\([^tr]\)/require.\1(t,\2/g' $f
# require.XXX(tblah) but not require.XXX(t, blah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\(t[^,]\)/require.\1(t,\2/g' $f
# require.XXX(rblah) but not require.XXX(r, blah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\(r[^,]\)/require.\1(t,\2/g' $f
gofmt -s -w $f
done
for f in $(git grep '\bassert := assert\.New(' | cut -d':' -f1 | sort -u); do
echo "=== assert: $f ==="
sed -i '/assert := assert.New(t)/d' $f
# assert.XXX(blah) but not assert.XXX(tblah) or assert.XXX(rblah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\([^tr]\)/assert.\1(t,\2/g' $f
# assert.XXX(tblah) but not assert.XXX(t, blah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\(t[^,]\)/assert.\1(t,\2/g' $f
# assert.XXX(rblah) but not assert.XXX(r, blah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\(r[^,]\)/assert.\1(t,\2/g' $f
gofmt -s -w $f
done
2022-01-20 16:46:23 +00:00
|
|
|
require.NoError(t, err)
|
2018-09-27 14:00:51 +00:00
|
|
|
if tc.Test != nil {
|
|
|
|
tc.Test(t, testConfig(t, cw))
|
|
|
|
}
|
2018-05-19 18:04:47 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func testConfig(t *testing.T, cw proxy.ConfigWatcher) *proxy.Config {
|
|
|
|
t.Helper()
|
|
|
|
|
|
|
|
select {
|
|
|
|
case cfg := <-cw.Watch():
|
|
|
|
return cfg
|
|
|
|
|
|
|
|
case <-time.After(1 * time.Second):
|
|
|
|
t.Fatal("no configuration loaded")
|
|
|
|
return nil // satisfy compiler
|
|
|
|
}
|
|
|
|
}
|
2018-10-03 19:37:53 +00:00
|
|
|
|
|
|
|
func TestCatalogCommand_noTabs(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
if strings.ContainsRune(New(nil, nil).Help(), '\t') {
|
|
|
|
t.Fatal("help has tabs")
|
|
|
|
}
|
|
|
|
}
|