Files
FlociClone/compatibility-tests/compat-terraform/test/apigateway_rest_readback.bats
2026-09-22 08:57:00 -04:00

141 lines
6.2 KiB
Bash

#!/usr/bin/env bats
# API Gateway REST Read-Back Compatibility Test
#
# GetMethod dropped requestParameters, GetRestApi dropped policy, and GetStage dropped
# accessLogSettings, tracingEnabled and tags. Every write succeeded, but the reads came back
# without the values, so each plan proposed the same three in-place updates forever. With a
# deployment trigger that hashes the method, the re-apply failed outright with "Provider
# produced inconsistent final plan". This verifies the module applies, reads back what it
# wrote, converges on a re-apply, and survives an in-place method change.
setup_file() {
load 'test_helper/common-setup'
APIGW_TF_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/apigateway-rest-readback-tf" && pwd)"
cd "$APIGW_TF_DIR"
echo "# === API Gateway REST Read-Back Test ===" >&3
echo "# Endpoint: $FLOCI_ENDPOINT" >&3
echo "# Config: $APIGW_TF_DIR" >&3
rm -rf .terraform .terraform.lock.hcl terraform.tfstate* 2>/dev/null || true
echo "# --- terraform init ---" >&3
run terraform init -input=false -no-color
if [ "$status" -ne 0 ]; then
echo "# terraform init failed: $output" >&3
return 1
fi
echo "# --- terraform apply ---" >&3
run terraform apply -var="endpoint=${FLOCI_ENDPOINT}" -input=false -auto-approve -no-color
if [ "$status" -ne 0 ]; then
echo "# terraform apply failed: $output" >&3
return 1
fi
}
teardown_file() {
load 'test_helper/common-setup'
APIGW_TF_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/apigateway-rest-readback-tf" && pwd)"
cd "$APIGW_TF_DIR"
terraform destroy -var="endpoint=${FLOCI_ENDPOINT}" -input=false -auto-approve -no-color || true
rm -rf .terraform .terraform.lock.hcl terraform.tfstate* 2>/dev/null || true
}
setup() {
load 'test_helper/common-setup'
APIGW_TF_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/apigateway-rest-readback-tf" && pwd)"
}
@test "API Gateway read-back: GetMethod returns requestParameters" {
API_ID=$(terraform -chdir="$APIGW_TF_DIR" output -raw rest_api_id)
RESOURCE_ID=$(terraform -chdir="$APIGW_TF_DIR" output -raw resource_id)
run aws_cmd apigateway get-method --rest-api-id "$API_ID" --resource-id "$RESOURCE_ID" \
--http-method ANY --query 'requestParameters."method.request.path.proxy"' --output text
assert_success
assert_output "True"
}
@test "API Gateway read-back: GetRestApi returns the policy" {
API_ID=$(terraform -chdir="$APIGW_TF_DIR" output -raw rest_api_id)
run aws_cmd apigateway get-rest-api --rest-api-id "$API_ID" --query policy --output text
assert_success
assert_output --partial "execute-api:Invoke"
}
@test "API Gateway read-back: GetStage returns access logs, tracing and tags" {
API_ID=$(terraform -chdir="$APIGW_TF_DIR" output -raw rest_api_id)
run aws_cmd apigateway get-stage --rest-api-id "$API_ID" --stage-name local \
--query '[accessLogSettings.format, tracingEnabled, tags.env]' --output text
assert_success
assert_output "\$context.requestId \$context.status True local"
}
# The failure from the bug report: the method read back without requestParameters, so it
# differed between plan and apply, the deployment trigger hash moved mid-apply, and the
# re-apply died with "Provider produced inconsistent final plan".
#
# The re-apply may still replace the deployment once, whatever the server returns:
# aws_api_gateway_method's create does not read the method back, so unset collections
# (request_models, authorization_scopes) stay null in state until the first refresh fills
# them in as empty, and that moves the trigger hash a single time. The stage then follows the
# new deployment id, so only the method and the policy must stay untouched here.
@test "API Gateway read-back: re-apply succeeds" {
cd "$APIGW_TF_DIR"
run terraform apply -var="endpoint=${FLOCI_ENDPOINT}" -input=false -auto-approve -no-color
assert_success
refute_output --partial "inconsistent final plan"
refute_output --partial "aws_api_gateway_method.proxy: Modifying"
refute_output --partial "aws_api_gateway_rest_api_policy.api: Modifying"
}
# The critical assertion: before the fix every plan proposed the same three updates forever.
@test "API Gateway read-back: plan after re-apply reports no changes" {
cd "$APIGW_TF_DIR"
run terraform plan -var="endpoint=${FLOCI_ENDPOINT}" -input=false -no-color -detailed-exitcode
assert_success
assert_output --partial "No changes"
}
# Changing a method request parameter goes through UpdateMethod patch operations and changes
# the deployment trigger hash. This is where "inconsistent final plan" used to surface.
@test "API Gateway read-back: changing a request parameter applies and re-plans clean" {
cd "$APIGW_TF_DIR"
run terraform apply -var="endpoint=${FLOCI_ENDPOINT}" -var="extra_request_parameter=true" \
-input=false -auto-approve -no-color
assert_success
refute_output --partial "inconsistent final plan"
run terraform plan -var="endpoint=${FLOCI_ENDPOINT}" -var="extra_request_parameter=true" \
-input=false -no-color -detailed-exitcode
assert_success
assert_output --partial "No changes"
}
# Stage tag changes go through TagResource on the stage ARN, which used to tag the REST API
# instead, so the stage never showed the new value and the plan never settled.
@test "API Gateway read-back: changing a stage tag lands on the stage and re-plans clean" {
cd "$APIGW_TF_DIR"
run terraform apply -var="endpoint=${FLOCI_ENDPOINT}" -var="extra_request_parameter=true" \
-var="stage_env=staging" -input=false -auto-approve -no-color
assert_success
API_ID=$(terraform -chdir="$APIGW_TF_DIR" output -raw rest_api_id)
run aws_cmd apigateway get-stage --rest-api-id "$API_ID" --stage-name local \
--query 'tags.env' --output text
assert_success
assert_output "staging"
run aws_cmd apigateway get-rest-api --rest-api-id "$API_ID" --query 'tags' --output text
assert_success
assert_output "None"
run terraform plan -var="endpoint=${FLOCI_ENDPOINT}" -var="extra_request_parameter=true" \
-var="stage_env=staging" -input=false -no-color -detailed-exitcode
assert_success
assert_output --partial "No changes"
}