[API Gateway] Add integration test for conflicted TCP listeners (#16225)

This commit is contained in:
Andrew Stucki 2023-02-10 12:34:01 -05:00 committed by GitHub
parent 4be4dd7af0
commit 6177653a6a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 142 additions and 0 deletions

View File

@ -705,6 +705,11 @@ func (c *configSnapshotAPIGateway) ToIngress(datacenter string) (configSnapshotI
continue continue
} }
if !c.GatewayConfig.ListenerIsReady(name) {
// skip any listeners that might be in an invalid state
continue
}
ingressListener := structs.IngressListener{ ingressListener := structs.IngressListener{
Port: listener.Port, Port: listener.Port,
Protocol: string(listener.Protocol), Protocol: string(listener.Protocol),

View File

@ -713,6 +713,25 @@ type APIGatewayConfigEntry struct {
RaftIndex RaftIndex
} }
func (e *APIGatewayConfigEntry) ListenerIsReady(name string) bool {
for _, condition := range e.Status.Conditions {
if !condition.Resource.IsSame(&ResourceReference{
Kind: APIGateway,
SectionName: name,
Name: e.Name,
EnterpriseMeta: e.EnterpriseMeta,
}) {
continue
}
if condition.Type == "Conflicted" && condition.Status == "True" {
return false
}
}
return true
}
func (e *APIGatewayConfigEntry) GetKind() string { func (e *APIGatewayConfigEntry) GetKind() string {
return APIGateway return APIGateway
} }

View File

@ -0,0 +1,3 @@
#!/bin/bash
snapshot_envoy_admin localhost:20000 api-gateway primary || true

View File

@ -0,0 +1,4 @@
services {
name = "api-gateway"
kind = "api-gateway"
}

View File

@ -0,0 +1,50 @@
#!/bin/bash
set -euo pipefail
upsert_config_entry primary '
kind = "api-gateway"
name = "api-gateway"
listeners = [
{
port = 9999
protocol = "tcp"
}
]
'
upsert_config_entry primary '
kind = "tcp-route"
name = "api-gateway-route-1"
services = [
{
name = "s1"
}
]
parents = [
{
name = "api-gateway"
}
]
'
upsert_config_entry primary '
kind = "tcp-route"
name = "api-gateway-route-2"
services = [
{
name = "s2"
}
]
parents = [
{
name = "api-gateway"
}
]
'
register_services primary
gen_envoy_bootstrap api-gateway 20000 primary true
gen_envoy_bootstrap s1 19000
gen_envoy_bootstrap s2 19001

View File

@ -0,0 +1,3 @@
#!/bin/bash
export REQUIRED_SERVICES="$DEFAULT_REQUIRED_SERVICES api-gateway-primary"

View File

@ -0,0 +1,20 @@
#!/usr/bin/env bats
load helpers
@test "api gateway proxy admin is up on :20000" {
retry_default curl -f -s localhost:20000/stats -o /dev/null
}
@test "api gateway should have a conflicted status" {
assert_config_entry_status Accepted True Accepted primary api-gateway api-gateway
assert_config_entry_status Conflicted True RouteConflict primary api-gateway api-gateway
}
@test "api gateway should have no healthy endpoints for s1" {
assert_upstream_missing 127.0.0.1:20000 s1
}
@test "api gateway should have no healthy endpoints for s2" {
assert_upstream_missing 127.0.0.1:20000 s2
}

View File

@ -6,6 +6,11 @@ load helpers
retry_default curl -f -s localhost:20000/stats -o /dev/null retry_default curl -f -s localhost:20000/stats -o /dev/null
} }
@test "api gateway should have be accepted and not conflicted" {
assert_config_entry_status Accepted True Accepted primary api-gateway api-gateway
assert_config_entry_status Conflicted False NoConflict primary api-gateway api-gateway
}
@test "api gateway should have healthy endpoints for s1" { @test "api gateway should have healthy endpoints for s1" {
assert_upstream_has_endpoints_in_status 127.0.0.1:20000 s1 HEALTHY 1 assert_upstream_has_endpoints_in_status 127.0.0.1:20000 s1 HEALTHY 1
} }

View File

@ -318,6 +318,16 @@ function get_envoy_metrics {
get_all_envoy_metrics $HOSTPORT | grep "$METRICS" get_all_envoy_metrics $HOSTPORT | grep "$METRICS"
} }
function get_upstream_endpoint {
local HOSTPORT=$1
local CLUSTER_NAME=$2
run curl -s -f "http://${HOSTPORT}/clusters?format=json"
[ "$status" -eq 0 ]
echo "$output" | jq --raw-output "
.cluster_statuses[]
| select(.name|startswith(\"${CLUSTER_NAME}\"))"
}
function get_upstream_endpoint_in_status_count { function get_upstream_endpoint_in_status_count {
local HOSTPORT=$1 local HOSTPORT=$1
local CLUSTER_NAME=$2 local CLUSTER_NAME=$2
@ -343,6 +353,14 @@ function assert_upstream_has_endpoints_in_status_once {
[ "$GOT_COUNT" -eq $EXPECT_COUNT ] [ "$GOT_COUNT" -eq $EXPECT_COUNT ]
} }
function assert_upstream_missing {
local HOSTPORT=$1
local CLUSTER_NAME=$2
run retry_default get_upstream_endpoint $HOSTPORT $CLUSTER_NAME
echo "OUTPUT: $output $status"
[ "" == "$output" ]
}
function assert_upstream_has_endpoints_in_status { function assert_upstream_has_endpoints_in_status {
local HOSTPORT=$1 local HOSTPORT=$1
local CLUSTER_NAME=$2 local CLUSTER_NAME=$2
@ -761,6 +779,21 @@ function upsert_config_entry {
echo "$BODY" | docker_consul "$DC" config write - echo "$BODY" | docker_consul "$DC" config write -
} }
function assert_config_entry_status {
local TYPE="$1"
local STATUS="$2"
local REASON="$3"
local DC="$4"
local KIND="$5"
local NAME="$6"
local NS=${7:-}
local AP=${8:-}
local PEER=${9:-}
status=$(curl -s -f "consul-${DC}-client:8500/v1/config/${KIND}/${NAME}?passing&ns=${NS}&partition=${AP}&peer=${PEER}" | jq ".Status.Conditions[] | select(.Type == \"$TYPE\" and .Status == \"$STATUS\" and .Reason == \"$REASON\")")
[ -n "$status" ]
}
function delete_config_entry { function delete_config_entry {
local KIND=$1 local KIND=$1
local NAME=$2 local NAME=$2