test: slight refactoring ahead of peering testing improvements (#17387)
This commit is contained in:
parent
4859cfb47b
commit
00a9e03f44
|
@ -6,6 +6,7 @@ package assert
|
|||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
@ -14,15 +15,29 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/hashicorp/consul/sdk/testutil/retry"
|
||||
libcluster "github.com/hashicorp/consul/test/integration/consul-container/libs/cluster"
|
||||
"github.com/hashicorp/consul/test/integration/consul-container/libs/utils"
|
||||
"github.com/hashicorp/go-cleanhttp"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
libcluster "github.com/hashicorp/consul/test/integration/consul-container/libs/cluster"
|
||||
"github.com/hashicorp/consul/test/integration/consul-container/libs/utils"
|
||||
)
|
||||
|
||||
// GetEnvoyListenerTCPFilters validates that proxy was configured with tcp protocol and one rbac listener filter
|
||||
func GetEnvoyListenerTCPFilters(t *testing.T, adminPort int) {
|
||||
require.True(t, adminPort > 0)
|
||||
|
||||
GetEnvoyListenerTCPFiltersWithClient(
|
||||
t,
|
||||
cleanhttp.DefaultClient(),
|
||||
fmt.Sprintf("localhost:%d", adminPort),
|
||||
)
|
||||
}
|
||||
func GetEnvoyListenerTCPFiltersWithClient(
|
||||
t *testing.T,
|
||||
client *http.Client,
|
||||
addr string,
|
||||
) {
|
||||
var (
|
||||
dump string
|
||||
err error
|
||||
|
@ -32,7 +47,7 @@ func GetEnvoyListenerTCPFilters(t *testing.T, adminPort int) {
|
|||
}
|
||||
|
||||
retry.RunWith(failer(), t, func(r *retry.R) {
|
||||
dump, _, err = GetEnvoyOutput(adminPort, "config_dump", map[string]string{})
|
||||
dump, _, err = GetEnvoyOutputWithClient(client, addr, "config_dump", map[string]string{})
|
||||
if err != nil {
|
||||
r.Fatal("could not fetch envoy configuration")
|
||||
}
|
||||
|
@ -55,30 +70,55 @@ func GetEnvoyListenerTCPFilters(t *testing.T, adminPort int) {
|
|||
require.Contains(t, filteredResult, "envoy.filters.network.tcp_proxy")
|
||||
}
|
||||
|
||||
// func GetEnvoyOutputWithClient(client *http.Client, addr string, path string, query map[string]string) (string, int, error) {
|
||||
|
||||
// AssertUpstreamEndpointStatus validates that proxy was configured with provided clusterName in the healthStatus
|
||||
func AssertUpstreamEndpointStatus(t *testing.T, adminPort int, clusterName, healthStatus string, count int) {
|
||||
var (
|
||||
clusters string
|
||||
err error
|
||||
require.True(t, adminPort > 0)
|
||||
AssertUpstreamEndpointStatusWithClient(
|
||||
t,
|
||||
cleanhttp.DefaultClient(),
|
||||
fmt.Sprintf("localhost:%d", adminPort),
|
||||
clusterName,
|
||||
healthStatus,
|
||||
count,
|
||||
)
|
||||
}
|
||||
func AssertUpstreamEndpointStatusWithClient(
|
||||
t *testing.T,
|
||||
client *http.Client,
|
||||
addr string,
|
||||
clusterName string,
|
||||
healthStatus string,
|
||||
count int,
|
||||
) {
|
||||
require.NotNil(t, client)
|
||||
require.NotEmpty(t, addr)
|
||||
failer := func() *retry.Timer {
|
||||
return &retry.Timer{Timeout: 30 * time.Second, Wait: 500 * time.Millisecond}
|
||||
}
|
||||
|
||||
retry.RunWith(failer(), t, func(r *retry.R) {
|
||||
clusters, _, err = GetEnvoyOutput(adminPort, "clusters", map[string]string{"format": "json"})
|
||||
clusters, statusCode, err := GetEnvoyOutputWithClient(client, addr, "clusters", map[string]string{"format": "json"})
|
||||
if err != nil {
|
||||
r.Fatal("could not fetch envoy clusters")
|
||||
}
|
||||
require.Equal(r, 200, statusCode)
|
||||
|
||||
filter := fmt.Sprintf(`.cluster_statuses[] | select(.name|contains("%s")) | [.host_statuses[].health_status.eds_health_status] | [select(.[] == "%s")] | length`, clusterName, healthStatus)
|
||||
filter := fmt.Sprintf(
|
||||
`.cluster_statuses[]
|
||||
| select(.name|contains("%s"))
|
||||
| [.host_statuses[].health_status.eds_health_status]
|
||||
| [select(.[] == "%s")]
|
||||
| length`,
|
||||
clusterName, healthStatus)
|
||||
results, err := utils.JQFilter(clusters, filter)
|
||||
require.NoErrorf(r, err, "could not found cluster name %s", clusterName)
|
||||
require.NoErrorf(r, err, "could not found cluster name %s in \n%s", clusterName, clusters)
|
||||
require.Len(r, results, 1) // the final part of the pipeline is "length" which only ever returns 1 result
|
||||
|
||||
resultToString := strings.Join(results, " ")
|
||||
result, err := strconv.Atoi(resultToString)
|
||||
result, err := strconv.Atoi(results[0])
|
||||
assert.NoError(r, err)
|
||||
require.Equal(r, count, result)
|
||||
require.Equal(r, count, result, "original results: %v", clusters)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -240,8 +280,12 @@ func AssertEnvoyRunning(t *testing.T, port int) {
|
|||
|
||||
func GetEnvoyOutput(port int, path string, query map[string]string) (string, int, error) {
|
||||
client := cleanhttp.DefaultClient()
|
||||
return GetEnvoyOutputWithClient(client, fmt.Sprintf("localhost:%d", port), path, query)
|
||||
}
|
||||
|
||||
func GetEnvoyOutputWithClient(client *http.Client, addr string, path string, query map[string]string) (string, int, error) {
|
||||
var u url.URL
|
||||
u.Host = fmt.Sprintf("localhost:%d", port)
|
||||
u.Host = addr
|
||||
u.Scheme = "http"
|
||||
if path != "" {
|
||||
u.Path = path
|
||||
|
|
|
@ -14,15 +14,24 @@ import (
|
|||
|
||||
// PeeringStatus verifies the peering connection is the specified state with a default retry.
|
||||
func PeeringStatus(t *testing.T, client *api.Client, peerName string, status api.PeeringState) {
|
||||
PeeringStatusOpts(t, client, peerName, status, nil)
|
||||
}
|
||||
|
||||
// PeeringStatusOpts verifies the peering connection is the specified
|
||||
// state with a default retry with options.
|
||||
func PeeringStatusOpts(t *testing.T, client *api.Client, peerName string, status api.PeeringState, opts *api.QueryOptions) {
|
||||
failer := func() *retry.Timer {
|
||||
return &retry.Timer{Timeout: 180 * time.Second, Wait: defaultWait}
|
||||
}
|
||||
|
||||
retry.RunWith(failer(), t, func(r *retry.R) {
|
||||
peering, _, err := client.Peerings().Read(context.Background(), peerName, &api.QueryOptions{})
|
||||
peering, _, err := client.Peerings().Read(context.Background(), peerName, opts)
|
||||
if err != nil {
|
||||
r.Fatal("error reading peering data")
|
||||
}
|
||||
if peering == nil {
|
||||
r.Fatal("peering not found")
|
||||
}
|
||||
if status != peering.State {
|
||||
r.Fatal("peering state did not match: got ", peering.State, " want ", status)
|
||||
}
|
||||
|
@ -31,15 +40,24 @@ func PeeringStatus(t *testing.T, client *api.Client, peerName string, status api
|
|||
|
||||
// PeeringExports verifies the correct number of exported services with a default retry.
|
||||
func PeeringExports(t *testing.T, client *api.Client, peerName string, exports int) {
|
||||
PeeringExportsOpts(t, client, peerName, exports, nil)
|
||||
}
|
||||
|
||||
// PeeringExportsOpts verifies the correct number of exported services
|
||||
// with a default retry with options.
|
||||
func PeeringExportsOpts(t *testing.T, client *api.Client, peerName string, exports int, opts *api.QueryOptions) {
|
||||
failer := func() *retry.Timer {
|
||||
return &retry.Timer{Timeout: defaultTimeout, Wait: defaultWait}
|
||||
}
|
||||
|
||||
retry.RunWith(failer(), t, func(r *retry.R) {
|
||||
peering, _, err := client.Peerings().Read(context.Background(), peerName, &api.QueryOptions{})
|
||||
peering, _, err := client.Peerings().Read(context.Background(), peerName, opts)
|
||||
if err != nil {
|
||||
r.Fatal("error reading peering data")
|
||||
}
|
||||
if peering == nil {
|
||||
r.Fatal("peering not found")
|
||||
}
|
||||
if exports != len(peering.StreamStatus.ExportedServices) {
|
||||
r.Fatal("peering exported services did not match: got ", len(peering.StreamStatus.ExportedServices), " want ", exports)
|
||||
}
|
||||
|
|
|
@ -17,8 +17,9 @@ import (
|
|||
|
||||
"github.com/hashicorp/consul/api"
|
||||
"github.com/hashicorp/consul/sdk/testutil/retry"
|
||||
libservice "github.com/hashicorp/consul/test/integration/consul-container/libs/service"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
libservice "github.com/hashicorp/consul/test/integration/consul-container/libs/service"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -55,22 +56,39 @@ func CatalogNodeExists(t *testing.T, c *api.Client, nodeName string) {
|
|||
func HTTPServiceEchoes(t *testing.T, ip string, port int, path string) {
|
||||
doHTTPServiceEchoes(t, ip, port, path, nil)
|
||||
}
|
||||
func HTTPServiceEchoesWithClient(t *testing.T, client *http.Client, addr string, path string) {
|
||||
doHTTPServiceEchoesWithClient(t, client, addr, path, nil)
|
||||
}
|
||||
|
||||
func HTTPServiceEchoesResHeader(t *testing.T, ip string, port int, path string, expectedResHeader map[string]string) {
|
||||
doHTTPServiceEchoes(t, ip, port, path, expectedResHeader)
|
||||
}
|
||||
func HTTPServiceEchoesResHeaderWithClient(t *testing.T, client *http.Client, addr string, path string, expectedResHeader map[string]string) {
|
||||
doHTTPServiceEchoesWithClient(t, client, addr, path, expectedResHeader)
|
||||
}
|
||||
|
||||
// HTTPServiceEchoes verifies that a post to the given ip/port combination returns the data
|
||||
// in the response body. Optional path can be provided to differentiate requests.
|
||||
func doHTTPServiceEchoes(t *testing.T, ip string, port int, path string, expectedResHeader map[string]string) {
|
||||
client := cleanhttp.DefaultClient()
|
||||
addr := fmt.Sprintf("%s:%d", ip, port)
|
||||
doHTTPServiceEchoesWithClient(t, client, addr, path, expectedResHeader)
|
||||
}
|
||||
|
||||
func doHTTPServiceEchoesWithClient(
|
||||
t *testing.T,
|
||||
client *http.Client,
|
||||
addr string,
|
||||
path string,
|
||||
expectedResHeader map[string]string,
|
||||
) {
|
||||
const phrase = "hello"
|
||||
|
||||
failer := func() *retry.Timer {
|
||||
return &retry.Timer{Timeout: defaultHTTPTimeout, Wait: defaultHTTPWait}
|
||||
}
|
||||
|
||||
client := cleanhttp.DefaultClient()
|
||||
url := fmt.Sprintf("http://%s:%d", ip, port)
|
||||
url := "http://" + addr
|
||||
|
||||
if path != "" {
|
||||
url += "/" + path
|
||||
|
@ -85,6 +103,10 @@ func doHTTPServiceEchoes(t *testing.T, ip string, port int, path string, expecte
|
|||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
statusCode := res.StatusCode
|
||||
t.Logf("...got response code %d", statusCode)
|
||||
require.Equal(r, 200, statusCode)
|
||||
|
||||
body, err := io.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
r.Fatal("could not read response body ", url)
|
||||
|
@ -166,7 +188,7 @@ func AssertFortioNameWithClient(t *testing.T, urlbase string, name string, reqHo
|
|||
|
||||
m := fortioNameRE.FindStringSubmatch(string(body))
|
||||
require.GreaterOrEqual(r, len(m), 2)
|
||||
t.Logf("got response from server name %s", m[1])
|
||||
t.Logf("got response from server name %q expect %q", m[1], name)
|
||||
assert.Equal(r, name, m[1])
|
||||
})
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
package utils
|
||||
|
||||
import "github.com/hashicorp/consul/api"
|
||||
|
||||
func PartitionOrDefault(name string) string {
|
||||
if name == "" {
|
||||
return "default"
|
||||
}
|
||||
return name
|
||||
}
|
||||
func NamespaceOrDefault(name string) string {
|
||||
if name == "" {
|
||||
return "default"
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
func DefaultToEmpty(name string) string {
|
||||
if name == "default" {
|
||||
return ""
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
// PartitionQueryOptions returns an *api.QueryOptions with the given partition
|
||||
// field set only if the partition is non-default. This helps when writing
|
||||
// tests for joint use in OSS and ENT.
|
||||
func PartitionQueryOptions(partition string) *api.QueryOptions {
|
||||
return &api.QueryOptions{
|
||||
Partition: DefaultToEmpty(partition),
|
||||
}
|
||||
}
|
|
@ -55,6 +55,8 @@ func GetLatestImageName() string {
|
|||
return LatestImageName
|
||||
}
|
||||
|
||||
func IsEnterprise() bool { return isInEnterpriseRepo }
|
||||
|
||||
func DockerImage(image, version string) string {
|
||||
v := image + ":" + version
|
||||
if strings.Contains(image, DefaultImageNameENT) && isSemVer(version) {
|
||||
|
|
|
@ -9,4 +9,5 @@ package utils
|
|||
const (
|
||||
defaultImageName = DefaultImageNameOSS
|
||||
ImageVersionSuffix = ""
|
||||
isInEnterpriseRepo = false
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue