moto/tests/test_elbv2/test_elbv2_target_groups.py

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

720 lines
24 KiB
Python
Raw Normal View History

import boto3
from botocore.exceptions import ClientError
import pytest
from moto import mock_elbv2, mock_ec2
2022-08-13 09:49:43 +00:00
from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID
from .test_elbv2 import create_load_balancer
@mock_ec2
@mock_elbv2
def test_create_target_group_with_invalid_healthcheck_protocol():
_, vpc, _, _, _, conn = create_load_balancer()
# Can't create a target group with an invalid protocol
with pytest.raises(ClientError) as exc:
conn.create_target_group(
Name="a-target",
Protocol="HTTP",
Port=8080,
VpcId=vpc.id,
HealthCheckProtocol="/HTTP",
HealthCheckPort="8080",
HealthCheckPath="/",
HealthCheckIntervalSeconds=5,
HealthCheckTimeoutSeconds=5,
HealthyThresholdCount=5,
UnhealthyThresholdCount=2,
Matcher={"HttpCode": "200"},
)
err = exc.value.response["Error"]
assert err["Code"] == "ValidationError"
assert (
err["Message"]
== "Value /HTTP at 'healthCheckProtocol' failed to satisfy constraint: Member must satisfy enum value set: ['HTTPS', 'HTTP', 'TCP', 'TLS', 'UDP', 'TCP_UDP', 'GENEVE']"
)
@mock_elbv2
@mock_ec2
2022-03-21 20:55:19 +00:00
def test_create_target_group_with_tags():
response, vpc, _, _, _, conn = create_load_balancer()
response = conn.create_target_group(
Name="a-target",
Protocol="HTTP",
Port=8080,
VpcId=vpc.id,
HealthCheckProtocol="HTTP",
HealthCheckPort="8080",
HealthCheckPath="/",
HealthCheckIntervalSeconds=5,
HealthCheckTimeoutSeconds=5,
HealthyThresholdCount=5,
UnhealthyThresholdCount=2,
Matcher={"HttpCode": "200"},
Tags=[{"Key": "key1", "Value": "val1"}],
)
target_group = response["TargetGroups"][0]
target_group_arn = target_group["TargetGroupArn"]
# Add tags to the target group
conn.add_tags(
2022-03-21 20:55:19 +00:00
ResourceArns=[target_group_arn],
Tags=[{"Key": "key2", "Value": "val2"}],
)
tags = conn.describe_tags(ResourceArns=[target_group_arn])["TagDescriptions"][0][
"Tags"
]
assert tags == [{"Key": "key1", "Value": "val1"}, {"Key": "key2", "Value": "val2"}]
2022-03-21 20:55:19 +00:00
# Verify they can be removed
conn.remove_tags(ResourceArns=[target_group_arn], TagKeys=["key1"])
tags = conn.describe_tags(ResourceArns=[target_group_arn])["TagDescriptions"][0][
2022-03-21 20:55:19 +00:00
"Tags"
]
assert tags == [{"Key": "key2", "Value": "val2"}]
2022-03-21 20:55:19 +00:00
@mock_elbv2
@mock_ec2
def test_create_target_group_and_listeners():
response, vpc, _, _, _, conn = create_load_balancer()
load_balancer_arn = response["LoadBalancers"][0]["LoadBalancerArn"]
2022-03-21 20:55:19 +00:00
response = conn.create_target_group(
Name="a-target",
Protocol="HTTP",
Port=8080,
VpcId=vpc.id,
HealthCheckProtocol="HTTP",
HealthCheckPort="8080",
HealthCheckPath="/",
HealthCheckIntervalSeconds=5,
HealthCheckTimeoutSeconds=5,
HealthyThresholdCount=5,
UnhealthyThresholdCount=2,
Matcher={"HttpCode": "200"},
)
target_group = response["TargetGroups"][0]
target_group_arn = target_group["TargetGroupArn"]
assert target_group["HealthCheckProtocol"] == "HTTP"
# Check it's in the describe_target_groups response
response = conn.describe_target_groups()
assert len(response["TargetGroups"]) == 1
# Plain HTTP listener
response = conn.create_listener(
LoadBalancerArn=load_balancer_arn,
Protocol="HTTP",
Port=80,
2022-03-21 20:55:19 +00:00
DefaultActions=[{"Type": "forward", "TargetGroupArn": target_group_arn}],
)
listener = response["Listeners"][0]
assert listener["Port"] == 80
assert listener["Protocol"] == "HTTP"
assert listener["DefaultActions"] == [
{"TargetGroupArn": target_group_arn, "Type": "forward"}
]
http_listener_arn = listener["ListenerArn"]
response = conn.describe_target_groups(
LoadBalancerArn=load_balancer_arn, Names=["a-target"]
)
assert len(response["TargetGroups"]) == 1
# And another with SSL
2022-03-21 20:55:19 +00:00
actions = {"Type": "forward", "TargetGroupArn": target_group_arn}
response = conn.create_listener(
LoadBalancerArn=load_balancer_arn,
Protocol="HTTPS",
Port=443,
Certificates=[
{"CertificateArn": f"arn:aws:iam:{ACCOUNT_ID}:server-certificate/test-cert"}
],
DefaultActions=[actions],
)
listener = response["Listeners"][0]
assert listener["Port"] == 443
assert listener["Protocol"] == "HTTPS"
assert listener["Certificates"] == [
{"CertificateArn": f"arn:aws:iam:{ACCOUNT_ID}:server-certificate/test-cert"}
]
assert listener["DefaultActions"] == [
{"TargetGroupArn": target_group_arn, "Type": "forward"}
]
https_listener_arn = listener["ListenerArn"]
response = conn.describe_listeners(LoadBalancerArn=load_balancer_arn)
assert len(response["Listeners"]) == 2
response = conn.describe_listeners(ListenerArns=[https_listener_arn])
assert len(response["Listeners"]) == 1
listener = response["Listeners"][0]
assert listener["Port"] == 443
assert listener["Protocol"] == "HTTPS"
response = conn.describe_listeners(
ListenerArns=[http_listener_arn, https_listener_arn]
)
assert len(response["Listeners"]) == 2
conn.create_rule(
ListenerArn=http_listener_arn,
Conditions=[{"Field": "path-pattern", "Values": ["/*"]}],
Priority=3,
Actions=[actions],
)
# Try to delete the target group and it fails because there's a
# listener referencing it
with pytest.raises(ClientError) as e:
2022-03-21 20:55:19 +00:00
conn.delete_target_group(TargetGroupArn=target_group_arn)
assert e.value.operation_name == "DeleteTargetGroup"
assert (
e.value.response["Error"]["Message"]
== f"The target group 'arn:aws:elasticloadbalancing:us-east-1:{ACCOUNT_ID}:targetgroup/a-target/50dc6c495c0c9188' is currently in use by a listener or a rule"
)
# Delete one listener
response = conn.describe_listeners(LoadBalancerArn=load_balancer_arn)
assert len(response["Listeners"]) == 2
conn.delete_listener(ListenerArn=http_listener_arn)
response = conn.describe_listeners(LoadBalancerArn=load_balancer_arn)
assert len(response["Listeners"]) == 1
# Then delete the load balancer
conn.delete_load_balancer(LoadBalancerArn=load_balancer_arn)
# It's gone
response = conn.describe_load_balancers()
assert len(response["LoadBalancers"]) == 0
# And it deleted the remaining listener
with pytest.raises(ClientError) as e:
conn.describe_listeners(ListenerArns=[http_listener_arn, https_listener_arn])
assert e.value.response["Error"]["Code"] == "ListenerNotFound"
# But not the target groups
response = conn.describe_target_groups()
assert len(response["TargetGroups"]) == 1
# Which we'll now delete
2022-03-21 20:55:19 +00:00
conn.delete_target_group(TargetGroupArn=target_group_arn)
response = conn.describe_target_groups()
assert len(response["TargetGroups"]) == 0
@mock_elbv2
@mock_ec2
def test_create_target_group_without_non_required_parameters():
response, vpc, _, _, _, conn = create_load_balancer()
# request without HealthCheckIntervalSeconds parameter
# which is default to 30 seconds
response = conn.create_target_group(
Name="a-target",
Protocol="HTTP",
Port=8080,
VpcId=vpc.id,
HealthCheckProtocol="HTTP",
HealthCheckPort="8080",
)
assert len(response.get("TargetGroups", [])) == 1
@mock_elbv2
@mock_ec2
def test_create_invalid_target_group_long_name():
conn = boto3.client("elbv2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="172.28.7.0/24", InstanceTenancy="default")
# Fail to create target group with name which length is 33
long_name = "A" * 33
with pytest.raises(ClientError) as exc:
conn.create_target_group(
Name=long_name,
Protocol="HTTP",
Port=8080,
VpcId=vpc.id,
HealthCheckProtocol="HTTP",
HealthCheckPort="8080",
HealthCheckPath="/",
HealthCheckIntervalSeconds=5,
HealthCheckTimeoutSeconds=5,
HealthyThresholdCount=5,
UnhealthyThresholdCount=2,
Matcher={"HttpCode": "200"},
)
err = exc.value.response["Error"]
assert err["Code"] == "ValidationError"
assert (
err["Message"]
== "Target group name 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' cannot be longer than '32' characters"
)
@mock_elbv2
@mock_ec2
@pytest.mark.parametrize("name", ["-name", "name-", "-name-", "Na--me"])
def test_create_invalid_target_group_invalid_characters(name):
conn = boto3.client("elbv2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="172.28.7.0/24", InstanceTenancy="default")
with pytest.raises(ClientError) as exc:
conn.create_target_group(
Name=name,
Protocol="HTTP",
Port=8080,
VpcId=vpc.id,
HealthCheckProtocol="HTTP",
HealthCheckPort="8080",
HealthCheckPath="/",
HealthCheckIntervalSeconds=5,
HealthCheckTimeoutSeconds=5,
HealthyThresholdCount=5,
UnhealthyThresholdCount=2,
Matcher={"HttpCode": "200"},
)
err = exc.value.response["Error"]
assert err["Code"] == "ValidationError"
assert (
err["Message"]
== f"1 validation error detected: Value '{name}' at 'targetGroup.targetGroupArn.targetGroupName' failed to satisfy constraint: Member must satisfy regular expression pattern: (?!.*--)(?!^-)(?!.*-$)^[A-Za-z0-9-]+$"
)
@mock_elbv2
@mock_ec2
@pytest.mark.parametrize("name", ["example.com", "test@test"])
def test_create_invalid_target_group_alphanumeric_characters(name):
conn = boto3.client("elbv2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="172.28.7.0/24", InstanceTenancy="default")
with pytest.raises(ClientError) as exc:
conn.create_target_group(
Name=name,
Protocol="HTTP",
Port=8080,
VpcId=vpc.id,
HealthCheckProtocol="HTTP",
HealthCheckPort="8080",
HealthCheckPath="/",
HealthCheckIntervalSeconds=5,
HealthCheckTimeoutSeconds=5,
HealthyThresholdCount=5,
UnhealthyThresholdCount=2,
Matcher={"HttpCode": "200"},
)
err = exc.value.response["Error"]
assert err["Code"] == "ValidationError"
assert (
err["Message"]
== f"Target group name '{name}' can only contain characters that are alphanumeric characters or hyphens(-)"
)
@mock_elbv2
@mock_ec2
@pytest.mark.parametrize("name", ["name", "Name", "000"])
def test_create_valid_target_group_valid_names(name):
conn = boto3.client("elbv2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="172.28.7.0/24", InstanceTenancy="default")
conn.create_target_group(
Name=name,
Protocol="HTTP",
Port=8080,
VpcId=vpc.id,
HealthCheckProtocol="HTTP",
HealthCheckPort="8080",
HealthCheckPath="/",
HealthCheckIntervalSeconds=5,
HealthCheckTimeoutSeconds=5,
HealthyThresholdCount=5,
UnhealthyThresholdCount=2,
Matcher={"HttpCode": "200"},
)
@mock_ec2
@mock_elbv2
def test_target_group_attributes():
response, vpc, _, _, _, conn = create_load_balancer()
response = conn.create_target_group(
Name="a-target",
Protocol="HTTP",
Port=8080,
VpcId=vpc.id,
HealthCheckProtocol="HTTP",
HealthCheckPort="8080",
HealthCheckPath="/",
HealthCheckIntervalSeconds=5,
HealthCheckTimeoutSeconds=5,
HealthyThresholdCount=5,
UnhealthyThresholdCount=2,
Matcher={"HttpCode": "200"},
)
target_group = response["TargetGroups"][0]
# Check it's in the describe_target_groups response
response = conn.describe_target_groups()
assert len(response["TargetGroups"]) == 1
target_group_arn = target_group["TargetGroupArn"]
# check if Names filter works
response = conn.describe_target_groups(Names=[])
response = conn.describe_target_groups(Names=["a-target"])
assert len(response["TargetGroups"]) == 1
target_group_arn = target_group["TargetGroupArn"]
# The attributes should start with the two defaults
response = conn.describe_target_group_attributes(TargetGroupArn=target_group_arn)
assert len(response["Attributes"]) == 5
attributes = {attr["Key"]: attr["Value"] for attr in response["Attributes"]}
assert attributes["deregistration_delay.timeout_seconds"] == "300"
assert attributes["stickiness.enabled"] == "false"
assert attributes["waf.fail_open.enabled"] == "false"
# Add cookie stickiness
response = conn.modify_target_group_attributes(
TargetGroupArn=target_group_arn,
Attributes=[
{"Key": "stickiness.enabled", "Value": "true"},
{"Key": "stickiness.type", "Value": "lb_cookie"},
],
)
# The response should have only the keys updated
assert len(response["Attributes"]) == 2
attributes = {attr["Key"]: attr["Value"] for attr in response["Attributes"]}
assert attributes["stickiness.type"] == "lb_cookie"
assert attributes["stickiness.enabled"] == "true"
# These new values should be in the full attribute list
response = conn.describe_target_group_attributes(TargetGroupArn=target_group_arn)
assert len(response["Attributes"]) == 6
attributes = {attr["Key"]: attr["Value"] for attr in response["Attributes"]}
assert attributes["stickiness.type"] == "lb_cookie"
assert attributes["stickiness.enabled"] == "true"
@mock_elbv2
@mock_ec2
def test_create_target_group_invalid_protocol():
elbv2 = boto3.client("elbv2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="172.28.7.0/24", InstanceTenancy="default")
# Can't create a target group with an invalid protocol
with pytest.raises(ClientError) as ex:
elbv2.create_target_group(
Name="a-target",
Protocol="HTTP",
Port=8080,
VpcId=vpc.id,
HealthCheckProtocol="/HTTP",
HealthCheckPort="8080",
HealthCheckPath="/",
HealthCheckIntervalSeconds=5,
HealthCheckTimeoutSeconds=5,
HealthyThresholdCount=5,
UnhealthyThresholdCount=2,
Matcher={"HttpCode": "200"},
)
err = ex.value.response["Error"]
assert err["Code"] == "ValidationError"
assert (
"Value /HTTP at 'healthCheckProtocol' failed to satisfy constraint"
in err["Message"]
)
@mock_elbv2
def test_describe_invalid_target_group():
conn = boto3.client("elbv2", region_name="us-east-1")
# Check error raises correctly
with pytest.raises(ClientError) as exc:
conn.describe_target_groups(Names=["invalid"])
err = exc.value.response["Error"]
assert err["Code"] == "TargetGroupNotFound"
assert err["Message"] == "The specified target group does not exist."
@mock_elbv2
@mock_ec2
def test_describe_target_groups_no_arguments():
response, vpc, _, _, _, conn = create_load_balancer()
assert "LoadBalancerArn" in response["LoadBalancers"][0]
conn.create_target_group(
Name="a-target",
Protocol="HTTP",
Port=8080,
VpcId=vpc.id,
HealthCheckProtocol="HTTP",
HealthCheckPort="8080",
HealthCheckPath="/",
HealthCheckIntervalSeconds=5,
HealthCheckTimeoutSeconds=5,
HealthyThresholdCount=5,
UnhealthyThresholdCount=2,
Matcher={"HttpCode": "201"},
)
groups = conn.describe_target_groups()["TargetGroups"]
assert len(groups) == 1
assert groups[0]["Matcher"] == {"HttpCode": "201"}
@mock_elbv2
@mock_ec2
def test_modify_target_group():
client = boto3.client("elbv2", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="172.28.7.0/24", InstanceTenancy="default")
response = client.create_target_group(
Name="a-target",
Protocol="HTTP",
Port=8080,
VpcId=vpc.id,
HealthCheckProtocol="HTTP",
HealthCheckPort="8080",
HealthCheckPath="/",
HealthCheckIntervalSeconds=5,
HealthCheckTimeoutSeconds=5,
HealthyThresholdCount=5,
UnhealthyThresholdCount=2,
Matcher={"HttpCode": "200"},
)
arn = response["TargetGroups"][0]["TargetGroupArn"]
client.modify_target_group(
TargetGroupArn=arn,
HealthCheckProtocol="HTTPS",
HealthCheckPort="8081",
HealthCheckPath="/status",
HealthCheckIntervalSeconds=10,
HealthCheckTimeoutSeconds=10,
HealthyThresholdCount=10,
UnhealthyThresholdCount=4,
Matcher={"HttpCode": "200-399"},
)
response = client.describe_target_groups(TargetGroupArns=[arn])
assert response["TargetGroups"][0]["Matcher"]["HttpCode"] == "200-399"
assert response["TargetGroups"][0]["HealthCheckIntervalSeconds"] == 10
assert response["TargetGroups"][0]["HealthCheckPath"] == "/status"
assert response["TargetGroups"][0]["HealthCheckPort"] == "8081"
assert response["TargetGroups"][0]["HealthCheckProtocol"] == "HTTPS"
assert response["TargetGroups"][0]["HealthCheckTimeoutSeconds"] == 10
assert response["TargetGroups"][0]["HealthyThresholdCount"] == 10
assert response["TargetGroups"][0]["Protocol"] == "HTTP"
assert response["TargetGroups"][0]["ProtocolVersion"] == "HTTP1"
assert response["TargetGroups"][0]["UnhealthyThresholdCount"] == 4
@mock_elbv2
@mock_ec2
@pytest.mark.parametrize("target_type", ["instance", "ip", "lambda", "alb", "other"])
def test_create_target_group_with_target_type(target_type):
response, _, _, _, _, conn = create_load_balancer()
response = conn.create_target_group(Name="a-target", TargetType=target_type)
group = response["TargetGroups"][0]
assert "TargetGroupArn" in group
assert group["TargetGroupName"] == "a-target"
assert group["TargetType"] == target_type
assert "Protocol" not in group
assert "VpcId" not in group
group = conn.describe_target_groups()["TargetGroups"][0]
assert "TargetGroupArn" in group
assert group["TargetGroupName"] == "a-target"
assert group["TargetType"] == target_type
assert "Protocol" not in group
assert "VpcId" not in group
@mock_elbv2
@mock_ec2
def test_delete_target_group_after_modifying_listener():
client = boto3.client("elbv2", region_name="us-east-1")
response, vpc, _, _, _, conn = create_load_balancer()
load_balancer_arn = response["LoadBalancers"][0]["LoadBalancerArn"]
response = client.create_target_group(
Name="a-target", Protocol="HTTP", Port=8080, VpcId=vpc.id
)
target_group_arn1 = response["TargetGroups"][0]["TargetGroupArn"]
response = client.create_target_group(
Name="a-target-2", Protocol="HTTPS", Port=8081, VpcId=vpc.id
)
target_group_arn2 = response["TargetGroups"][0]["TargetGroupArn"]
response = conn.create_listener(
LoadBalancerArn=load_balancer_arn,
Protocol="HTTP",
Port=80,
DefaultActions=[{"Type": "forward", "TargetGroupArn": target_group_arn1}],
)
listener_arn = response["Listeners"][0]["ListenerArn"]
client.modify_listener(
ListenerArn=listener_arn,
DefaultActions=[{"Type": "forward", "TargetGroupArn": target_group_arn2}],
)
response = conn.describe_listeners(LoadBalancerArn=load_balancer_arn)
default_actions = response["Listeners"][0]["DefaultActions"]
assert default_actions == [{"Type": "forward", "TargetGroupArn": target_group_arn2}]
# Target Group 1 can now be deleted, as the LB points to group 2
client.delete_target_group(TargetGroupArn=target_group_arn1)
# Sanity check - we're still pointing to group 2
response = conn.describe_listeners(LoadBalancerArn=load_balancer_arn)
default_actions = response["Listeners"][0]["DefaultActions"]
assert default_actions == [{"Type": "forward", "TargetGroupArn": target_group_arn2}]
@mock_elbv2
@mock_ec2
def test_create_listener_with_multiple_target_groups():
client = boto3.client("elbv2", region_name="us-east-1")
response, vpc, _, _, _, conn = create_load_balancer()
load_balancer_arn = response["LoadBalancers"][0]["LoadBalancerArn"]
response = client.create_target_group(
Name="a-target", Protocol="HTTP", Port=8080, VpcId=vpc.id
)
target_group_arn1 = response["TargetGroups"][0]["TargetGroupArn"]
response = client.create_target_group(
Name="a-target-2", Protocol="HTTPS", Port=8081, VpcId=vpc.id
)
target_group_arn2 = response["TargetGroups"][0]["TargetGroupArn"]
conn.create_listener(
LoadBalancerArn=load_balancer_arn,
Protocol="HTTP",
Port=80,
DefaultActions=[
{
"Type": "forward",
"ForwardConfig": {
"TargetGroups": [
{"TargetGroupArn": target_group_arn1, "Weight": 100},
{"TargetGroupArn": target_group_arn2, "Weight": 0},
],
"TargetGroupStickinessConfig": {
"Enabled": False,
"DurationSeconds": 300,
},
},
}
],
)
response = conn.describe_listeners(LoadBalancerArn=load_balancer_arn)
listener = response["Listeners"][0]
groups = listener["DefaultActions"][0]["ForwardConfig"]["TargetGroups"]
assert len(groups) == 2
assert {"TargetGroupArn": target_group_arn1, "Weight": 100} in groups
assert {"TargetGroupArn": target_group_arn2, "Weight": 0} in groups
@mock_elbv2
@mock_ec2
def test_create_listener_with_invalid_target_group():
response, _, _, _, _, conn = create_load_balancer()
load_balancer_arn = response["LoadBalancers"][0]["LoadBalancerArn"]
with pytest.raises(ClientError) as exc:
conn.create_listener(
LoadBalancerArn=load_balancer_arn,
Protocol="HTTP",
Port=80,
DefaultActions=[
{
"Type": "forward",
"ForwardConfig": {
"TargetGroups": [{"TargetGroupArn": "unknown", "Weight": 100}]
},
}
],
)
err = exc.value.response["Error"]
assert err["Code"] == "TargetGroupNotFound"
assert err["Message"] == "Target group 'unknown' not found"
@mock_elbv2
@mock_ec2
def test_delete_target_group_while_listener_still_exists():
client = boto3.client("elbv2", region_name="us-east-1")
response, vpc, _, _, _, conn = create_load_balancer()
load_balancer_arn = response["LoadBalancers"][0]["LoadBalancerArn"]
response = client.create_target_group(
Name="a-target", Protocol="HTTP", Port=8080, VpcId=vpc.id
)
target_group_arn1 = response["TargetGroups"][0]["TargetGroupArn"]
response = conn.create_listener(
LoadBalancerArn=load_balancer_arn,
Protocol="HTTP",
Port=80,
DefaultActions=[
{
"Type": "forward",
"ForwardConfig": {
"TargetGroups": [
{"TargetGroupArn": target_group_arn1, "Weight": 100}
]
},
}
],
)
listener_arn = response["Listeners"][0]["ListenerArn"]
# Deletion does not succeed if the Listener still exists
with pytest.raises(ClientError) as exc:
client.delete_target_group(TargetGroupArn=target_group_arn1)
err = exc.value.response["Error"]
assert err["Code"] == "ResourceInUse"
assert (
err["Message"]
== f"The target group '{target_group_arn1}' is currently in use by a listener or a rule"
)
client.delete_listener(ListenerArn=listener_arn)
# Deletion does succeed now that the listener is deleted
client.delete_target_group(TargetGroupArn=target_group_arn1)