Merge pull request #4216 from hashicorp/NET-2252-add-assert-fortioname (#16212)

NET-2252: integration tests: add assert.FortioName
This commit is contained in:
Anita Akaeze 2023-02-09 09:45:31 -05:00 committed by GitHub
parent 834ef73e8a
commit 01fa1031de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 99 additions and 43 deletions

View File

@ -3,6 +3,8 @@ package assert
import ( import (
"fmt" "fmt"
"io" "io"
"net/http"
"regexp"
"strings" "strings"
"testing" "testing"
"time" "time"
@ -13,6 +15,7 @@ import (
"github.com/hashicorp/consul/api" "github.com/hashicorp/consul/api"
"github.com/hashicorp/consul/sdk/testutil/retry" "github.com/hashicorp/consul/sdk/testutil/retry"
libservice "github.com/hashicorp/consul/test/integration/consul-container/libs/service" libservice "github.com/hashicorp/consul/test/integration/consul-container/libs/service"
"github.com/stretchr/testify/assert"
) )
const ( const (
@ -89,6 +92,30 @@ func ServiceLogContains(t *testing.T, service libservice.Service, target string)
return strings.Contains(logs, target) return strings.Contains(logs, target)
} }
// AssertFortioName asserts that the fortio service replying at urlbase/debug
// has a `FORTIO_NAME` env variable set. This validates that the client is sending
// traffic to the right envoy proxy.
//
// It retries with timeout defaultHTTPTimeout and wait defaultHTTPWait.
func AssertFortioName(t *testing.T, urlbase string, name string) {
t.Helper()
var fortioNameRE = regexp.MustCompile(("\nFORTIO_NAME=(.+)\n"))
var body []byte
retry.RunWith(&retry.Timer{Timeout: defaultHTTPTimeout, Wait: defaultHTTPWait}, t, func(r *retry.R) {
resp, err := http.Get(fmt.Sprintf("%s/debug?env=dump", urlbase))
if err != nil {
r.Error(err)
return
}
defer resp.Body.Close()
body, err = io.ReadAll(resp.Body)
require.NoError(t, err)
})
m := fortioNameRE.FindStringSubmatch(string(body))
require.GreaterOrEqual(t, len(m), 2)
assert.Equal(t, name, m[1])
}
// AssertContainerState validates service container status // AssertContainerState validates service container status
func AssertContainerState(t *testing.T, service libservice.Service, state string) { func AssertContainerState(t *testing.T, service libservice.Service, state string) {
containerStatus, err := service.GetStatus() containerStatus, err := service.GetStatus()

View File

@ -514,8 +514,13 @@ func newContainerRequest(config Config, opts containerOpts) (podRequest, consulR
"8443/tcp", // Envoy Gateway Listener "8443/tcp", // Envoy Gateway Listener
"8079/tcp", // Envoy App Listener "8079/tcp", // Envoy App Listener - grpc port used by static-server
"8080/tcp", // Envoy App Listener "8078/tcp", // Envoy App Listener - grpc port used by static-server-v1
"8077/tcp", // Envoy App Listener - grpc port used by static-server-v2
"8080/tcp", // Envoy App Listener - http port used by static-server
"8081/tcp", // Envoy App Listener - http port used by static-server-v1
"8082/tcp", // Envoy App Listener - http port used by static-server-v2
"9998/tcp", // Envoy App Listener "9998/tcp", // Envoy App Listener
"9999/tcp", // Envoy App Listener "9999/tcp", // Envoy App Listener
}, },

View File

@ -16,9 +16,11 @@ const (
) )
type ServiceOpts struct { type ServiceOpts struct {
Name string Name string
ID string ID string
Meta map[string]string Meta map[string]string
HTTPPort int
GRPCPort int
} }
func CreateAndRegisterStaticServerAndSidecar(node libcluster.Agent, serviceOpts *ServiceOpts) (Service, Service, error) { func CreateAndRegisterStaticServerAndSidecar(node libcluster.Agent, serviceOpts *ServiceOpts) (Service, Service, error) {
@ -32,7 +34,7 @@ func CreateAndRegisterStaticServerAndSidecar(node libcluster.Agent, serviceOpts
req := &api.AgentServiceRegistration{ req := &api.AgentServiceRegistration{
Name: serviceOpts.Name, Name: serviceOpts.Name,
ID: serviceOpts.ID, ID: serviceOpts.ID,
Port: 8080, Port: serviceOpts.HTTPPort,
Connect: &api.AgentServiceConnect{ Connect: &api.AgentServiceConnect{
SidecarService: &api.AgentServiceRegistration{ SidecarService: &api.AgentServiceRegistration{
Proxy: &api.AgentServiceConnectProxyConfig{}, Proxy: &api.AgentServiceConnectProxyConfig{},
@ -40,7 +42,7 @@ func CreateAndRegisterStaticServerAndSidecar(node libcluster.Agent, serviceOpts
}, },
Check: &api.AgentServiceCheck{ Check: &api.AgentServiceCheck{
Name: "Static Server Listening", Name: "Static Server Listening",
TCP: fmt.Sprintf("127.0.0.1:%d", 8080), TCP: fmt.Sprintf("127.0.0.1:%d", serviceOpts.HTTPPort),
Interval: "10s", Interval: "10s",
Status: api.HealthPassing, Status: api.HealthPassing,
}, },
@ -52,7 +54,7 @@ func CreateAndRegisterStaticServerAndSidecar(node libcluster.Agent, serviceOpts
} }
// Create a service and proxy instance // Create a service and proxy instance
serverService, err := NewExampleService(context.Background(), StaticServerServiceName, 8080, 8079, node) serverService, err := NewExampleService(context.Background(), serviceOpts.ID, serviceOpts.HTTPPort, serviceOpts.GRPCPort, node)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
@ -60,7 +62,7 @@ func CreateAndRegisterStaticServerAndSidecar(node libcluster.Agent, serviceOpts
_ = serverService.Terminate() _ = serverService.Terminate()
}) })
serverConnectProxy, err := NewConnectService(context.Background(), fmt.Sprintf("%s-sidecar", StaticServerServiceName), serviceOpts.ID, 8080, node) // bindPort not used serverConnectProxy, err := NewConnectService(context.Background(), fmt.Sprintf("%s-sidecar", StaticServerServiceName), serviceOpts.ID, serviceOpts.HTTPPort, node) // bindPort not used
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }

View File

@ -68,9 +68,11 @@ func BasicPeeringTwoClustersSetup(
var err error var err error
// Create a service and proxy instance // Create a service and proxy instance
serviceOpts := libservice.ServiceOpts{ serviceOpts := libservice.ServiceOpts{
Name: libservice.StaticServerServiceName, Name: libservice.StaticServerServiceName,
ID: "static-server", ID: "static-server",
Meta: map[string]string{"version": ""}, Meta: map[string]string{"version": ""},
HTTPPort: 8080,
GRPCPort: 8079,
} }
serverSidecarService, _, err := libservice.CreateAndRegisterStaticServerAndSidecar(clientNode, &serviceOpts) serverSidecarService, _, err := libservice.CreateAndRegisterStaticServerAndSidecar(clientNode, &serviceOpts)
require.NoError(t, err) require.NoError(t, err)
@ -107,6 +109,7 @@ func BasicPeeringTwoClustersSetup(
libassert.AssertUpstreamEndpointStatus(t, adminPort, fmt.Sprintf("static-server.default.%s.external", DialingPeerName), "HEALTHY", 1) libassert.AssertUpstreamEndpointStatus(t, adminPort, fmt.Sprintf("static-server.default.%s.external", DialingPeerName), "HEALTHY", 1)
_, port := clientSidecarService.GetAddr() _, port := clientSidecarService.GetAddr()
libassert.HTTPServiceEchoes(t, "localhost", port, "") libassert.HTTPServiceEchoes(t, "localhost", port, "")
libassert.AssertFortioName(t, fmt.Sprintf("http://localhost:%d", port), "static-server")
return &BuiltCluster{ return &BuiltCluster{
Cluster: acceptingCluster, Cluster: acceptingCluster,

View File

@ -1,6 +1,7 @@
package basic package basic
import ( import (
"fmt"
"testing" "testing"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -33,6 +34,7 @@ func TestBasicConnectService(t *testing.T) {
libassert.AssertContainerState(t, clientService, "running") libassert.AssertContainerState(t, clientService, "running")
libassert.HTTPServiceEchoes(t, "localhost", port, "") libassert.HTTPServiceEchoes(t, "localhost", port, "")
libassert.AssertFortioName(t, fmt.Sprintf("http://localhost:%d", port), "static-server")
} }
func createCluster(t *testing.T) *libcluster.Cluster { func createCluster(t *testing.T) *libcluster.Cluster {
@ -72,8 +74,10 @@ func createServices(t *testing.T, cluster *libcluster.Cluster) libservice.Servic
client := node.GetClient() client := node.GetClient()
// Create a service and proxy instance // Create a service and proxy instance
serviceOpts := &libservice.ServiceOpts{ serviceOpts := &libservice.ServiceOpts{
Name: libservice.StaticServerServiceName, Name: libservice.StaticServerServiceName,
ID: "static-server", ID: "static-server",
HTTPPort: 8080,
GRPCPort: 8079,
} }
// Create a service and proxy instance // Create a service and proxy instance

View File

@ -70,6 +70,7 @@ func TestAccessLogs(t *testing.T) {
// Validate Custom JSON // Validate Custom JSON
require.Eventually(t, func() bool { require.Eventually(t, func() bool {
libassert.HTTPServiceEchoes(t, "localhost", port, "banana") libassert.HTTPServiceEchoes(t, "localhost", port, "banana")
libassert.AssertFortioName(t, fmt.Sprintf("http://localhost:%d", port), "static-server")
client := libassert.ServiceLogContains(t, clientService, "\"banana_path\":\"/banana\"") client := libassert.ServiceLogContains(t, clientService, "\"banana_path\":\"/banana\"")
server := libassert.ServiceLogContains(t, serverService, "\"banana_path\":\"/banana\"") server := libassert.ServiceLogContains(t, serverService, "\"banana_path\":\"/banana\"")
return client && server return client && server
@ -111,6 +112,7 @@ func TestAccessLogs(t *testing.T) {
_, port = clientService.GetAddr() _, port = clientService.GetAddr()
require.Eventually(t, func() bool { require.Eventually(t, func() bool {
libassert.HTTPServiceEchoes(t, "localhost", port, "orange") libassert.HTTPServiceEchoes(t, "localhost", port, "orange")
libassert.AssertFortioName(t, fmt.Sprintf("http://localhost:%d", port), "static-server")
client := libassert.ServiceLogContains(t, clientService, "Orange you glad I didn't say banana: /orange, -") client := libassert.ServiceLogContains(t, clientService, "Orange you glad I didn't say banana: /orange, -")
server := libassert.ServiceLogContains(t, serverService, "Orange you glad I didn't say banana: /orange, -") server := libassert.ServiceLogContains(t, serverService, "Orange you glad I didn't say banana: /orange, -")
return client && server return client && server
@ -137,8 +139,10 @@ func createServices(t *testing.T, cluster *libcluster.Cluster) (libservice.Servi
// Create a service and proxy instance // Create a service and proxy instance
serviceOpts := &libservice.ServiceOpts{ serviceOpts := &libservice.ServiceOpts{
Name: libservice.StaticServerServiceName, Name: libservice.StaticServerServiceName,
ID: "static-server", ID: "static-server",
HTTPPort: 8080,
GRPCPort: 8079,
} }
// Create a service and proxy instance // Create a service and proxy instance

View File

@ -3,6 +3,7 @@ package peering
import ( import (
"context" "context"
"encoding/pem" "encoding/pem"
"fmt"
"testing" "testing"
"time" "time"
@ -93,6 +94,7 @@ func TestPeering_RotateServerAndCAThenFail_(t *testing.T) {
_, port := clientSidecarService.GetAddr() _, port := clientSidecarService.GetAddr()
libassert.HTTPServiceEchoes(t, "localhost", port, "") libassert.HTTPServiceEchoes(t, "localhost", port, "")
libassert.AssertFortioName(t, fmt.Sprintf("http://localhost:%d", port), "static-server")
} }
testutil.RunStep(t, "rotate exporting cluster's root CA", func(t *testing.T) { testutil.RunStep(t, "rotate exporting cluster's root CA", func(t *testing.T) {
@ -142,6 +144,7 @@ func TestPeering_RotateServerAndCAThenFail_(t *testing.T) {
// Connectivity should still be contained // Connectivity should still be contained
_, port := clientSidecarService.GetAddr() _, port := clientSidecarService.GetAddr()
libassert.HTTPServiceEchoes(t, "localhost", port, "") libassert.HTTPServiceEchoes(t, "localhost", port, "")
libassert.AssertFortioName(t, fmt.Sprintf("http://localhost:%d", port), "static-server")
verifySidecarHasTwoRootCAs(t, clientSidecarService) verifySidecarHasTwoRootCAs(t, clientSidecarService)
}) })
@ -163,6 +166,7 @@ func TestPeering_RotateServerAndCAThenFail_(t *testing.T) {
_, port := clientSidecarService.GetAddr() _, port := clientSidecarService.GetAddr()
libassert.HTTPServiceEchoes(t, "localhost", port, "") libassert.HTTPServiceEchoes(t, "localhost", port, "")
libassert.AssertFortioName(t, fmt.Sprintf("http://localhost:%d", port), "static-server")
}) })
} }

View File

@ -110,6 +110,7 @@ func TestPeering_Upgrade_ControlPlane_MGW(t *testing.T) {
require.NoError(t, clientSidecarService.Restart()) require.NoError(t, clientSidecarService.Restart())
libassert.AssertUpstreamEndpointStatus(t, adminPort, fmt.Sprintf("static-server.default.%s.external", libtopology.DialingPeerName), "HEALTHY", 1) libassert.AssertUpstreamEndpointStatus(t, adminPort, fmt.Sprintf("static-server.default.%s.external", libtopology.DialingPeerName), "HEALTHY", 1)
libassert.HTTPServiceEchoes(t, "localhost", port, "") libassert.HTTPServiceEchoes(t, "localhost", port, "")
libassert.AssertFortioName(t, fmt.Sprintf("http://localhost:%d", port), "static-server")
} }
for _, tc := range tcs { for _, tc := range tcs {

View File

@ -80,6 +80,7 @@ func TestPeering_UpgradeToTarget_fromLatest(t *testing.T) {
require.NoError(t, clientSidecarService.Restart()) require.NoError(t, clientSidecarService.Restart())
libassert.AssertUpstreamEndpointStatus(t, adminPort, fmt.Sprintf("static-server.default.%s.external", libtopology.DialingPeerName), "HEALTHY", 1) libassert.AssertUpstreamEndpointStatus(t, adminPort, fmt.Sprintf("static-server.default.%s.external", libtopology.DialingPeerName), "HEALTHY", 1)
libassert.HTTPServiceEchoes(t, "localhost", port, "") libassert.HTTPServiceEchoes(t, "localhost", port, "")
libassert.AssertFortioName(t, fmt.Sprintf("http://localhost:%d", port), "static-server")
} }
for _, tc := range tcs { for _, tc := range tcs {

View File

@ -76,28 +76,26 @@ func TestTrafficManagement_ServiceWithSubsets(t *testing.T) {
err := cluster.ConfigEntryWrite(serviceResolver) err := cluster.ConfigEntryWrite(serviceResolver)
require.NoError(t, err) require.NoError(t, err)
serverService, serverServiceV1, serverServiceV2, clientService := createService(t, cluster) serverConnectProxy, serverConnectProxyV1, serverConnectProxyV2, clientConnectProxy := createService(t, cluster)
_, port := clientService.GetAddr() _, port := clientConnectProxy.GetAddr()
_, adminPort := clientService.GetAdminAddr() _, adminPort := clientConnectProxy.GetAdminAddr()
_, serverAdminPort := serverService.GetAdminAddr() _, serverAdminPort := serverConnectProxy.GetAdminAddr()
_, serverAdminPortV1 := serverServiceV1.GetAdminAddr() _, serverAdminPortV1 := serverConnectProxyV1.GetAdminAddr()
_, serverAdminPortV2 := serverServiceV2.GetAdminAddr() _, serverAdminPortV2 := serverConnectProxyV2.GetAdminAddr()
// validate client and proxy is up and running // validate client and proxy is up and running
libassert.AssertContainerState(t, clientService, "running") libassert.AssertContainerState(t, clientConnectProxy, "running")
// TO-DO: static-client upstream should be able to connect to static-server-v2 via upstream s2
libassert.HTTPServiceEchoes(t, "localhost", port, "") libassert.HTTPServiceEchoes(t, "localhost", port, "")
libassert.AssertUpstreamEndpointStatus(t, adminPort, "v2.static-server.default", "HEALTHY", 1) libassert.AssertUpstreamEndpointStatus(t, adminPort, "v2.static-server.default", "HEALTHY", 1)
// Upgrade cluster, restart sidecars then begin service traffic validation // Upgrade cluster, restart sidecars then begin service traffic validation
require.NoError(t, cluster.StandardUpgrade(t, context.Background(), tc.targetVersion)) require.NoError(t, cluster.StandardUpgrade(t, context.Background(), tc.targetVersion))
require.NoError(t, clientService.Restart()) require.NoError(t, clientConnectProxy.Restart())
require.NoError(t, serverService.Restart()) require.NoError(t, serverConnectProxy.Restart())
require.NoError(t, serverServiceV1.Restart()) require.NoError(t, serverConnectProxyV1.Restart())
require.NoError(t, serverServiceV2.Restart()) require.NoError(t, serverConnectProxyV2.Restart())
// POST upgrade validation; repeat client & proxy validation // POST upgrade validation; repeat client & proxy validation
libassert.HTTPServiceEchoes(t, "localhost", port, "") libassert.HTTPServiceEchoes(t, "localhost", port, "")
@ -129,7 +127,8 @@ func TestTrafficManagement_ServiceWithSubsets(t *testing.T) {
libassert.AssertEnvoyPresentsCertURI(t, serverAdminPortV1, "static-server") libassert.AssertEnvoyPresentsCertURI(t, serverAdminPortV1, "static-server")
libassert.AssertEnvoyPresentsCertURI(t, serverAdminPortV2, "static-server") libassert.AssertEnvoyPresentsCertURI(t, serverAdminPortV2, "static-server")
// TO-DO: restart envoy sidecar and validate traffic management // static-client upstream should connect to static-server-v2 because the default subset value is to v2 set in the service resolver
libassert.AssertFortioName(t, fmt.Sprintf("http://localhost:%d", port), "static-server-v2")
} }
for _, tc := range tcs { for _, tc := range tcs {
@ -146,35 +145,41 @@ func createService(t *testing.T, cluster *libcluster.Cluster) (libservice.Servic
client := node.GetClient() client := node.GetClient()
serviceOpts := &libservice.ServiceOpts{ serviceOpts := &libservice.ServiceOpts{
Name: libservice.StaticServerServiceName, Name: libservice.StaticServerServiceName,
ID: "static-server", ID: "static-server",
HTTPPort: 8080,
GRPCPort: 8079,
} }
_, serverService, err := libservice.CreateAndRegisterStaticServerAndSidecar(node, serviceOpts) _, serverConnectProxy, err := libservice.CreateAndRegisterStaticServerAndSidecar(node, serviceOpts)
libassert.CatalogServiceExists(t, client, "static-server") libassert.CatalogServiceExists(t, client, "static-server")
require.NoError(t, err) require.NoError(t, err)
serviceOptsV1 := &libservice.ServiceOpts{ serviceOptsV1 := &libservice.ServiceOpts{
Name: libservice.StaticServerServiceName, Name: libservice.StaticServerServiceName,
ID: "static-server-v1", ID: "static-server-v1",
Meta: map[string]string{"version": "v1"}, Meta: map[string]string{"version": "v1"},
HTTPPort: 8081,
GRPCPort: 8078,
} }
_, serverServiceV1, err := libservice.CreateAndRegisterStaticServerAndSidecar(node, serviceOptsV1) _, serverConnectProxyV1, err := libservice.CreateAndRegisterStaticServerAndSidecar(node, serviceOptsV1)
libassert.CatalogServiceExists(t, client, "static-server") libassert.CatalogServiceExists(t, client, "static-server")
require.NoError(t, err) require.NoError(t, err)
serviceOptsV2 := &libservice.ServiceOpts{ serviceOptsV2 := &libservice.ServiceOpts{
Name: libservice.StaticServerServiceName, Name: libservice.StaticServerServiceName,
ID: "static-server-v2", ID: "static-server-v2",
Meta: map[string]string{"version": "v2"}, Meta: map[string]string{"version": "v2"},
HTTPPort: 8082,
GRPCPort: 8077,
} }
_, serverServiceV2, err := libservice.CreateAndRegisterStaticServerAndSidecar(node, serviceOptsV2) _, serverConnectProxyV2, err := libservice.CreateAndRegisterStaticServerAndSidecar(node, serviceOptsV2)
libassert.CatalogServiceExists(t, client, "static-server") libassert.CatalogServiceExists(t, client, "static-server")
require.NoError(t, err) require.NoError(t, err)
// Create a client proxy instance with the server as an upstream // Create a client proxy instance with the server as an upstream
clientService, err := libservice.CreateAndRegisterStaticClientSidecar(node, "", false) clientConnectProxy, err := libservice.CreateAndRegisterStaticClientSidecar(node, "", false)
require.NoError(t, err) require.NoError(t, err)
libassert.CatalogServiceExists(t, client, fmt.Sprintf("%s-sidecar-proxy", libservice.StaticClientServiceName)) libassert.CatalogServiceExists(t, client, fmt.Sprintf("%s-sidecar-proxy", libservice.StaticClientServiceName))
return serverService, serverServiceV1, serverServiceV2, clientService return serverConnectProxy, serverConnectProxyV1, serverConnectProxyV2, clientConnectProxy
} }