moto/tests/test_dax/test_dax.py

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

457 lines
16 KiB
Python
Raw Normal View History

2021-12-27 20:15:37 +00:00
"""Unit tests for dax-supported APIs."""
2021-12-27 20:15:37 +00:00
import boto3
import pytest
from botocore.exceptions import ClientError
2023-03-10 12:45:48 +00:00
2024-01-07 12:03:33 +00:00
from moto import mock_aws
2022-08-13 09:49:43 +00:00
from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID
2021-12-27 20:15:37 +00:00
# See our Development Tips on writing tests for hints on how to write good tests:
# http://docs.getmoto.org/en/latest/docs/contributing/development_tips/tests.html
2024-01-07 12:03:33 +00:00
@mock_aws
2021-12-27 20:15:37 +00:00
def test_create_cluster_minimal():
client = boto3.client("dax", region_name="us-east-2")
iam_role_arn = f"arn:aws:iam::{ACCOUNT_ID}:role/aws-service-role/dax.amazonaws.com/AWSServiceRoleForDAX"
created_cluster = client.create_cluster(
ClusterName="daxcluster",
NodeType="dax.t3.small",
ReplicationFactor=3,
IamRoleArn=iam_role_arn,
)["Cluster"]
described_cluster = client.describe_clusters(ClusterNames=["daxcluster"])[
"Clusters"
][0]
for cluster in [created_cluster, described_cluster]:
2023-03-10 12:45:48 +00:00
assert cluster["ClusterName"] == "daxcluster"
assert (
cluster["ClusterArn"]
== f"arn:aws:dax:us-east-2:{ACCOUNT_ID}:cache/daxcluster"
2021-12-27 20:15:37 +00:00
)
2023-03-10 12:45:48 +00:00
assert cluster["TotalNodes"] == 3
assert cluster["ActiveNodes"] == 0
assert cluster["NodeType"] == "dax.t3.small"
assert cluster["Status"] == "creating"
assert cluster["ClusterDiscoveryEndpoint"] == {"Port": 8111}
assert cluster["PreferredMaintenanceWindow"] == "thu:23:30-fri:00:30"
assert cluster["SubnetGroup"] == "default"
assert len(cluster["SecurityGroups"]) == 1
assert cluster["IamRoleArn"] == iam_role_arn
assert cluster["ParameterGroup"]["ParameterGroupName"] == "default.dax1.0"
assert cluster["SSEDescription"] == {"Status": "DISABLED"}
assert cluster["ClusterEndpointEncryptionType"] == "NONE"
2021-12-27 20:15:37 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2021-12-27 20:15:37 +00:00
def test_create_cluster_description():
client = boto3.client("dax", region_name="us-east-2")
iam_role_arn = f"arn:aws:iam::{ACCOUNT_ID}:role/aws-service-role/dax.amazonaws.com/AWSServiceRoleForDAX"
created_cluster = client.create_cluster(
ClusterName="daxcluster",
Description="my cluster",
NodeType="dax.t3.small",
ReplicationFactor=3,
IamRoleArn=iam_role_arn,
)["Cluster"]
described_cluster = client.describe_clusters(ClusterNames=["daxcluster"])[
"Clusters"
][0]
for cluster in [created_cluster, described_cluster]:
2023-03-10 12:45:48 +00:00
assert cluster["ClusterName"] == "daxcluster"
assert cluster["Description"] == "my cluster"
2021-12-27 20:15:37 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2021-12-27 20:15:37 +00:00
def test_create_cluster_with_sse_enabled():
client = boto3.client("dax", region_name="us-east-2")
iam_role_arn = f"arn:aws:iam::{ACCOUNT_ID}:role/aws-service-role/dax.amazonaws.com/AWSServiceRoleForDAX"
created_cluster = client.create_cluster(
ClusterName="daxcluster",
NodeType="dax.t3.small",
ReplicationFactor=3,
IamRoleArn=iam_role_arn,
SSESpecification={"Enabled": True},
2022-05-19 11:08:02 +00:00
ClusterEndpointEncryptionType="TLS",
2021-12-27 20:15:37 +00:00
)["Cluster"]
described_cluster = client.describe_clusters(ClusterNames=["daxcluster"])[
"Clusters"
][0]
for cluster in [created_cluster, described_cluster]:
2023-03-10 12:45:48 +00:00
assert cluster["ClusterName"] == "daxcluster"
assert cluster["SSEDescription"] == {"Status": "ENABLED"}
assert cluster["ClusterEndpointEncryptionType"] == "TLS"
2021-12-27 20:15:37 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2023-03-10 12:45:48 +00:00
@pytest.mark.parametrize(
"iam_role,expected",
(
("n/a", "ARNs must start with 'arn:': n/a"),
("arn:sth", "Second colon partition not found: arn:sth"),
("arn:sth:aws", "Third colon vendor not found: arn:sth:aws"),
(
"arn:sth:aws:else",
"Fourth colon (region/namespace delimiter) not found: arn:sth:aws:else",
),
(
"arn:sth:aws:else:eu-west-1",
"Fifth colon (namespace/relative-id delimiter) not found: arn:sth:aws:else:eu-west-1",
),
),
)
def test_create_cluster_invalid_arn(iam_role: str, expected: str):
2021-12-27 20:15:37 +00:00
client = boto3.client("dax", region_name="eu-west-1")
with pytest.raises(ClientError) as exc:
client.create_cluster(
ClusterName="1invalid",
NodeType="dax.t3.small",
ReplicationFactor=3,
2023-03-10 12:45:48 +00:00
IamRoleArn=iam_role,
2021-12-27 20:15:37 +00:00
)
err = exc.value.response["Error"]
2023-03-10 12:45:48 +00:00
assert err["Code"] == "InvalidParameterValueException"
assert err["Message"] == expected
2021-12-27 20:15:37 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2021-12-27 20:15:37 +00:00
@pytest.mark.parametrize(
"name", ["1invalid", "iИvalid", "in_valid", "invalid-", "in--valid"]
)
def test_create_cluster_invalid_name(name):
client = boto3.client("dax", region_name="eu-west-1")
with pytest.raises(ClientError) as exc:
client.create_cluster(
ClusterName=name,
NodeType="dax.t3.small",
ReplicationFactor=3,
IamRoleArn="arn:aws:iam::486285699788:role/apigatewayrole",
)
err = exc.value.response["Error"]
2023-03-10 12:45:48 +00:00
assert err["Code"] == "InvalidParameterValueException"
assert err["Message"] == (
2021-12-27 20:15:37 +00:00
"Cluster ID specified is not a valid identifier. Identifiers must begin with a letter; must contain only ASCII letters, digits, and hyphens; and must not end with a hyphen or contain two consecutive hyphens."
)
2024-01-07 12:03:33 +00:00
@mock_aws
2021-12-27 20:15:37 +00:00
@pytest.mark.parametrize(
"name", ["1invalid", "iИvalid", "in_valid", "invalid-", "in--valid"]
)
def test_describe_clusters_invalid_name(name):
client = boto3.client("dax", region_name="eu-west-1")
with pytest.raises(ClientError) as exc:
client.describe_clusters(ClusterNames=[name])
err = exc.value.response["Error"]
assert err["Code"] == "InvalidParameterValueException"
assert (
err["Message"]
== "Cluster ID specified is not a valid identifier. Identifiers must begin with a letter; must contain only ASCII letters, digits, and hyphens; and must not end with a hyphen or contain two consecutive hyphens."
2021-12-27 20:15:37 +00:00
)
2024-01-07 12:03:33 +00:00
@mock_aws
2021-12-27 20:15:37 +00:00
def test_delete_cluster_unknown():
client = boto3.client("dax", region_name="eu-west-1")
with pytest.raises(ClientError) as exc:
client.delete_cluster(ClusterName="unknown")
err = exc.value.response["Error"]
2023-03-10 12:45:48 +00:00
assert err["Code"] == "ClusterNotFoundFault"
assert err["Message"] == "Cluster not found."
2021-12-27 20:15:37 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2021-12-27 20:15:37 +00:00
def test_delete_cluster():
client = boto3.client("dax", region_name="eu-west-1")
iam_role_arn = f"arn:aws:iam::{ACCOUNT_ID}:role/aws-service-role/dax.amazonaws.com/AWSServiceRoleForDAX"
client.create_cluster(
ClusterName="daxcluster",
NodeType="dax.t3.small",
ReplicationFactor=2,
IamRoleArn=iam_role_arn,
)
client.delete_cluster(ClusterName="daxcluster")
for _ in range(0, 3):
# Cluster takes a while to delete...
cluster = client.describe_clusters(ClusterNames=["daxcluster"])["Clusters"][0]
2023-03-10 12:45:48 +00:00
assert cluster["Status"] == "deleting"
assert cluster["TotalNodes"] == 2
assert cluster["ActiveNodes"] == 0
assert "Nodes" not in cluster
2021-12-27 20:15:37 +00:00
with pytest.raises(ClientError) as exc:
client.describe_clusters(ClusterNames=["daxcluster"])
err = exc.value.response["Error"]
2023-03-10 12:45:48 +00:00
assert err["Code"] == "ClusterNotFoundFault"
2021-12-27 20:15:37 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2021-12-27 20:15:37 +00:00
def test_describe_cluster_unknown():
client = boto3.client("dax", region_name="eu-west-1")
with pytest.raises(ClientError) as exc:
client.describe_clusters(ClusterNames=["unknown"])
err = exc.value.response["Error"]
2023-03-10 12:45:48 +00:00
assert err["Code"] == "ClusterNotFoundFault"
assert err["Message"] == "Cluster unknown not found."
2021-12-27 20:15:37 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2021-12-27 20:15:37 +00:00
def test_describe_clusters_returns_all():
client = boto3.client("dax", region_name="us-east-1")
iam_role_arn = f"arn:aws:iam::{ACCOUNT_ID}:role/aws-service-role/dax.amazonaws.com/AWSServiceRoleForDAX"
for i in range(0, 50):
client.create_cluster(
ClusterName=f"daxcluster{i}",
NodeType="dax.t3.small",
ReplicationFactor=1,
IamRoleArn=iam_role_arn,
)
2023-03-10 12:45:48 +00:00
assert len(client.describe_clusters()["Clusters"]) == 50
2021-12-27 20:15:37 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2021-12-27 20:15:37 +00:00
def test_describe_clusters_paginates():
client = boto3.client("dax", region_name="us-east-1")
iam_role_arn = f"arn:aws:iam::{ACCOUNT_ID}:role/aws-service-role/dax.amazonaws.com/AWSServiceRoleForDAX"
for i in range(0, 50):
client.create_cluster(
ClusterName=f"daxcluster{i}",
NodeType="dax.t3.small",
ReplicationFactor=1,
IamRoleArn=iam_role_arn,
)
resp = client.describe_clusters(MaxResults=10)
2023-03-10 12:45:48 +00:00
assert len(resp["Clusters"]) == 10
assert "NextToken" in resp
2021-12-27 20:15:37 +00:00
resp = client.describe_clusters(MaxResults=10, NextToken=resp["NextToken"])
2023-03-10 12:45:48 +00:00
assert len(resp["Clusters"]) == 10
assert "NextToken" in resp
2021-12-27 20:15:37 +00:00
resp = client.describe_clusters(NextToken=resp["NextToken"])
2023-03-10 12:45:48 +00:00
assert len(resp["Clusters"]) == 30
assert "NextToken" not in resp
2021-12-27 20:15:37 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2021-12-27 20:15:37 +00:00
def test_describe_clusters_returns_nodes_after_some_time():
client = boto3.client("dax", region_name="us-east-2")
2023-03-10 12:45:48 +00:00
iam_role_arn = f"arn:aws:iam::{ACCOUNT_ID}:role/aws-service-role/dax.amazonaws.com/AWSServiceRoleForDAX"
2021-12-27 20:15:37 +00:00
client.create_cluster(
ClusterName="daxcluster",
NodeType="dax.t3.small",
ReplicationFactor=3,
2023-03-10 12:45:48 +00:00
IamRoleArn=iam_role_arn,
)
2021-12-27 20:15:37 +00:00
for _ in range(0, 3):
# Cluster takes a while to load...
cluster = client.describe_clusters(ClusterNames=["daxcluster"])["Clusters"][0]
2023-03-10 12:45:48 +00:00
assert cluster["Status"] == "creating"
assert "Nodes" not in cluster
2021-12-27 20:15:37 +00:00
# Finished loading by now
cluster = client.describe_clusters(ClusterNames=["daxcluster"])["Clusters"][0]
assert cluster["TotalNodes"] == 3
assert cluster["ActiveNodes"] == 0
assert cluster["Status"] == "available"
2021-12-27 20:15:37 +00:00
# Address Info is only available when the cluster is ready
endpoint = cluster["ClusterDiscoveryEndpoint"]
address = endpoint["Address"]
cluster_id = address.split(".")[1]
2023-03-10 12:45:48 +00:00
assert address == f"daxcluster.{cluster_id}.dax-clusters.us-east-2.amazonaws.com"
assert endpoint["Port"] == 8111
assert endpoint["URL"] == f"dax://{address}"
2021-12-27 20:15:37 +00:00
# Nodes are only shown when the cluster is ready
2023-03-10 12:45:48 +00:00
assert len(cluster["Nodes"]) == 3
2021-12-27 20:15:37 +00:00
for idx, a in enumerate(["a", "b", "c"]):
node = cluster["Nodes"][idx]
2023-03-10 12:45:48 +00:00
expected_node_address = (
2021-12-27 20:15:37 +00:00
f"daxcluster-{a}.{cluster_id}.nodes.dax-clusters.us-east-2.amazonaws.com"
)
2023-03-10 12:45:48 +00:00
assert node["NodeId"] == f"daxcluster-{a}"
assert node["Endpoint"]["Address"] == expected_node_address
assert node["Endpoint"]["Port"] == 8111
assert "AvailabilityZone" in node
assert node["NodeStatus"] == "available"
assert node["ParameterGroupStatus"] == "in-sync"
2021-12-27 20:15:37 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2021-12-27 20:15:37 +00:00
def test_list_tags_unknown():
client = boto3.client("dax", region_name="ap-southeast-1")
with pytest.raises(ClientError) as exc:
client.list_tags(ResourceName="unknown")
err = exc.value.response["Error"]
2023-03-10 12:45:48 +00:00
assert err["Code"] == "ClusterNotFoundFault"
2021-12-27 20:15:37 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2021-12-27 20:15:37 +00:00
def test_list_tags():
client = boto3.client("dax", region_name="ap-southeast-1")
cluster = client.create_cluster(
ClusterName="daxcluster",
NodeType="dax.t3.small",
ReplicationFactor=3,
IamRoleArn=f"arn:aws:iam::{ACCOUNT_ID}:role/aws-service-role/dax.amazonaws.com/AWSServiceRoleForDAX",
Tags=[
{"Key": "tag1", "Value": "value1"},
{"Key": "tag2", "Value": "value2"},
{"Key": "tag3", "Value": "value3"},
],
)["Cluster"]
for name in ["daxcluster", cluster["ClusterArn"]]:
resp = client.list_tags(ResourceName=name)
2023-03-10 12:45:48 +00:00
assert "NextToken" not in resp
assert resp["Tags"] == (
2021-12-27 20:15:37 +00:00
[
{"Key": "tag1", "Value": "value1"},
{"Key": "tag2", "Value": "value2"},
{"Key": "tag3", "Value": "value3"},
]
)
2024-01-07 12:03:33 +00:00
@mock_aws
2021-12-27 20:15:37 +00:00
def test_increase_replication_factor_unknown():
client = boto3.client("dax", region_name="ap-southeast-1")
with pytest.raises(ClientError) as exc:
client.increase_replication_factor(
ClusterName="unknown", NewReplicationFactor=2
)
err = exc.value.response["Error"]
2023-03-10 12:45:48 +00:00
assert err["Code"] == "ClusterNotFoundFault"
2021-12-27 20:15:37 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2021-12-27 20:15:37 +00:00
def test_increase_replication_factor():
client = boto3.client("dax", region_name="ap-southeast-1")
name = "daxcluster"
cluster = client.create_cluster(
ClusterName=name,
NodeType="dax.t3.small",
ReplicationFactor=2,
IamRoleArn=f"arn:aws:iam::{ACCOUNT_ID}:role/aws-service-role/dax.amazonaws.com/AWSServiceRoleForDAX",
Tags=[
{"Key": "tag1", "Value": "value1"},
{"Key": "tag2", "Value": "value2"},
{"Key": "tag3", "Value": "value3"},
],
)["Cluster"]
2023-03-10 12:45:48 +00:00
assert cluster["TotalNodes"] == 2
adjusted_cluster = client.increase_replication_factor(
2021-12-27 20:15:37 +00:00
ClusterName=name, NewReplicationFactor=5
)["Cluster"]
2023-03-10 12:45:48 +00:00
described_cluster = client.describe_clusters(ClusterNames=[name])["Clusters"][0]
2021-12-27 20:15:37 +00:00
2023-03-10 12:45:48 +00:00
assert adjusted_cluster["TotalNodes"] == 5
assert described_cluster["TotalNodes"] == 5
2021-12-27 20:15:37 +00:00
# Progress cluster until it's available
2023-03-10 12:45:48 +00:00
for _ in range(0, 3):
client.describe_clusters(ClusterNames=[name])
described_cluster = client.describe_clusters(ClusterNames=[name])["Clusters"][0]
node_ids = set([node["NodeId"] for node in described_cluster["Nodes"]])
2021-12-27 20:15:37 +00:00
2023-03-10 12:45:48 +00:00
assert node_ids == (
2021-12-27 20:15:37 +00:00
{f"{name}-a", f"{name}-b", f"{name}-c", f"{name}-d", f"{name}-e"}
)
2024-01-07 12:03:33 +00:00
@mock_aws
2021-12-27 20:15:37 +00:00
def test_decrease_replication_factor_unknown():
client = boto3.client("dax", region_name="ap-southeast-1")
with pytest.raises(ClientError) as exc:
client.decrease_replication_factor(
ClusterName="unknown", NewReplicationFactor=2
)
err = exc.value.response["Error"]
2023-03-10 12:45:48 +00:00
assert err["Code"] == "ClusterNotFoundFault"
2021-12-27 20:15:37 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2021-12-27 20:15:37 +00:00
def test_decrease_replication_factor():
client = boto3.client("dax", region_name="eu-west-1")
name = "daxcluster"
client.create_cluster(
ClusterName=name,
NodeType="dax.t3.small",
ReplicationFactor=5,
IamRoleArn=f"arn:aws:iam::{ACCOUNT_ID}:role/aws-service-role/dax.amazonaws.com/AWSServiceRoleForDAX",
)
2023-03-10 12:45:48 +00:00
adjusted_cluster = client.decrease_replication_factor(
2021-12-27 20:15:37 +00:00
ClusterName=name, NewReplicationFactor=3
)["Cluster"]
2023-03-10 12:45:48 +00:00
described_cluster = client.describe_clusters(ClusterNames=[name])["Clusters"][0]
2021-12-27 20:15:37 +00:00
2023-03-10 12:45:48 +00:00
assert adjusted_cluster["TotalNodes"] == 3
assert described_cluster["TotalNodes"] == 3
2021-12-27 20:15:37 +00:00
# Progress cluster until it's available
2023-03-10 12:45:48 +00:00
for _ in range(0, 3):
client.describe_clusters(ClusterNames=[name])
2021-12-27 20:15:37 +00:00
2023-03-10 12:45:48 +00:00
described_cluster = client.describe_clusters(ClusterNames=[name])["Clusters"][0]
node_ids = set([node["NodeId"] for node in described_cluster["Nodes"]])
assert node_ids == ({f"{name}-a", f"{name}-b", f"{name}-c"})
2021-12-27 20:15:37 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2021-12-27 20:15:37 +00:00
def test_decrease_replication_factor_specific_nodeids():
client = boto3.client("dax", region_name="ap-southeast-1")
name = "daxcluster"
client.create_cluster(
ClusterName=name,
NodeType="dax.t3.small",
ReplicationFactor=5,
IamRoleArn=f"arn:aws:iam::{ACCOUNT_ID}:role/aws-service-role/dax.amazonaws.com/AWSServiceRoleForDAX",
)
2023-03-10 12:45:48 +00:00
adjusted_cluster = client.decrease_replication_factor(
2021-12-27 20:15:37 +00:00
ClusterName=name,
NewReplicationFactor=3,
NodeIdsToRemove=["daxcluster-b", "daxcluster-c"],
)["Cluster"]
2023-03-10 12:45:48 +00:00
described_cluster = client.describe_clusters(ClusterNames=[name])["Clusters"][0]
2021-12-27 20:15:37 +00:00
2023-03-10 12:45:48 +00:00
assert adjusted_cluster["TotalNodes"] == 3
assert described_cluster["TotalNodes"] == 3
2021-12-27 20:15:37 +00:00
# Progress cluster until it's available
2023-03-10 12:45:48 +00:00
for _ in range(0, 3):
client.describe_clusters(ClusterNames=[name])
described_cluster = client.describe_clusters(ClusterNames=[name])["Clusters"][0]
node_ids = set([node["NodeId"] for node in described_cluster["Nodes"]])
2021-12-27 20:15:37 +00:00
2023-03-10 12:45:48 +00:00
assert node_ids == ({f"{name}-a", f"{name}-d", f"{name}-e"})