2021-12-07 12:09:13 +00:00
|
|
|
import boto3
|
|
|
|
import pytest
|
|
|
|
from botocore.exceptions import ClientError
|
2022-08-13 09:49:43 +00:00
|
|
|
from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID
|
2021-12-07 12:09:13 +00:00
|
|
|
|
2023-09-02 13:00:25 +00:00
|
|
|
from moto import mock_elasticache
|
|
|
|
|
|
|
|
|
2021-12-07 12:09:13 +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
|
|
|
|
|
|
|
|
|
|
|
|
@mock_elasticache
|
|
|
|
def test_create_user_no_password_required():
|
|
|
|
client = boto3.client("elasticache", region_name="ap-southeast-1")
|
|
|
|
user_id = "user1"
|
|
|
|
resp = client.create_user(
|
|
|
|
UserId=user_id,
|
|
|
|
UserName="User1",
|
|
|
|
Engine="Redis",
|
|
|
|
AccessString="on ~* +@all",
|
|
|
|
NoPasswordRequired=True,
|
|
|
|
)
|
|
|
|
|
2023-07-20 09:36:20 +00:00
|
|
|
assert resp["UserId"] == user_id
|
|
|
|
assert resp["UserName"] == "User1"
|
|
|
|
assert resp["Status"] == "active"
|
|
|
|
assert resp["Engine"] == "Redis"
|
|
|
|
assert resp["MinimumEngineVersion"] == "6.0"
|
|
|
|
assert resp["AccessString"] == "on ~* +@all"
|
|
|
|
assert resp["UserGroupIds"] == []
|
|
|
|
assert resp["Authentication"]["Type"] == "no-password"
|
|
|
|
assert "PasswordCount" not in resp["Authentication"]
|
|
|
|
assert (
|
|
|
|
resp["ARN"] == f"arn:aws:elasticache:ap-southeast-1:{ACCOUNT_ID}:user:{user_id}"
|
2021-12-07 12:09:13 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@mock_elasticache
|
|
|
|
def test_create_user_with_password_too_short():
|
|
|
|
client = boto3.client("elasticache", region_name="ap-southeast-1")
|
|
|
|
user_id = "user1"
|
|
|
|
with pytest.raises(ClientError) as exc:
|
|
|
|
client.create_user(
|
|
|
|
UserId=user_id,
|
|
|
|
UserName="User1",
|
|
|
|
Engine="Redis",
|
|
|
|
AccessString="on ~* +@all",
|
|
|
|
Passwords=["mysecretpass"],
|
|
|
|
)
|
|
|
|
err = exc.value.response["Error"]
|
2023-07-20 09:36:20 +00:00
|
|
|
assert err["Code"] == "InvalidParameterValue"
|
|
|
|
assert err["Message"] == "Passwords length must be between 16-128 characters."
|
2021-12-07 12:09:13 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_elasticache
|
|
|
|
def test_create_user_with_password():
|
|
|
|
client = boto3.client("elasticache", region_name="ap-southeast-1")
|
|
|
|
user_id = "user1"
|
|
|
|
resp = client.create_user(
|
|
|
|
UserId=user_id,
|
|
|
|
UserName="User1",
|
|
|
|
Engine="Redis",
|
|
|
|
AccessString="on ~* +@all",
|
|
|
|
Passwords=["mysecretpassthatsverylong"],
|
|
|
|
)
|
|
|
|
|
2023-07-20 09:36:20 +00:00
|
|
|
assert resp["UserId"] == user_id
|
|
|
|
assert resp["UserName"] == "User1"
|
|
|
|
assert resp["Status"] == "active"
|
|
|
|
assert resp["Engine"] == "Redis"
|
|
|
|
assert resp["MinimumEngineVersion"] == "6.0"
|
|
|
|
assert resp["AccessString"] == "on ~* +@all"
|
|
|
|
assert resp["UserGroupIds"] == []
|
|
|
|
assert resp["Authentication"]["Type"] == "password"
|
|
|
|
assert resp["Authentication"]["PasswordCount"] == 1
|
|
|
|
assert (
|
|
|
|
resp["ARN"] == f"arn:aws:elasticache:ap-southeast-1:{ACCOUNT_ID}:user:{user_id}"
|
2021-12-07 12:09:13 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@mock_elasticache
|
|
|
|
def test_create_user_without_password():
|
|
|
|
client = boto3.client("elasticache", region_name="ap-southeast-1")
|
|
|
|
with pytest.raises(ClientError) as exc:
|
|
|
|
client.create_user(
|
|
|
|
UserId="user1", UserName="User1", Engine="Redis", AccessString="?"
|
|
|
|
)
|
|
|
|
err = exc.value.response["Error"]
|
2023-07-20 09:36:20 +00:00
|
|
|
assert err["Code"] == "InvalidParameterValue"
|
|
|
|
assert (
|
|
|
|
err["Message"]
|
|
|
|
== "No password was provided. If you want to create/update the user without password, please use the NoPasswordRequired flag."
|
2021-12-07 12:09:13 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@mock_elasticache
|
|
|
|
def test_create_user_twice():
|
|
|
|
client = boto3.client("elasticache", region_name="ap-southeast-1")
|
|
|
|
user_id = "user1"
|
|
|
|
client.create_user(
|
|
|
|
UserId=user_id,
|
|
|
|
UserName="User1",
|
|
|
|
Engine="Redis",
|
|
|
|
AccessString="on ~* +@all",
|
|
|
|
Passwords=["mysecretpassthatsverylong"],
|
|
|
|
)
|
|
|
|
|
|
|
|
with pytest.raises(ClientError) as exc:
|
|
|
|
client.create_user(
|
|
|
|
UserId=user_id,
|
|
|
|
UserName="User1",
|
|
|
|
Engine="Redis",
|
|
|
|
AccessString="on ~* +@all",
|
|
|
|
Passwords=["mysecretpassthatsverylong"],
|
|
|
|
)
|
|
|
|
err = exc.value.response["Error"]
|
2023-07-20 09:36:20 +00:00
|
|
|
assert err["Code"] == "UserAlreadyExists"
|
|
|
|
assert err["Message"] == "User user1 already exists."
|
2021-12-07 12:09:13 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_elasticache
|
|
|
|
def test_delete_user_unknown():
|
|
|
|
client = boto3.client("elasticache", region_name="ap-southeast-1")
|
|
|
|
with pytest.raises(ClientError) as exc:
|
|
|
|
client.delete_user(UserId="unknown")
|
|
|
|
err = exc.value.response["Error"]
|
2023-07-20 09:36:20 +00:00
|
|
|
assert err["Code"] == "UserNotFound"
|
|
|
|
assert err["Message"] == "User unknown not found."
|
2021-12-07 12:09:13 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_elasticache
|
|
|
|
def test_delete_user():
|
|
|
|
client = boto3.client("elasticache", region_name="ap-southeast-1")
|
|
|
|
|
|
|
|
client.create_user(
|
|
|
|
UserId="user1",
|
|
|
|
UserName="User1",
|
|
|
|
Engine="Redis",
|
|
|
|
AccessString="on ~* +@all",
|
|
|
|
Passwords=["mysecretpassthatsverylong"],
|
|
|
|
)
|
|
|
|
|
|
|
|
client.delete_user(UserId="user1")
|
|
|
|
|
|
|
|
# Initial status is 'deleting'
|
|
|
|
resp = client.describe_users(UserId="user1")
|
2023-07-20 09:36:20 +00:00
|
|
|
assert resp["Users"][0]["Status"] == "deleting"
|
2021-12-07 12:09:13 +00:00
|
|
|
|
|
|
|
# User is only deleted after some time
|
|
|
|
with pytest.raises(ClientError) as exc:
|
|
|
|
client.describe_users(UserId="unknown")
|
2023-07-20 09:36:20 +00:00
|
|
|
assert exc.value.response["Error"]["Code"] == "UserNotFound"
|
2021-12-07 12:09:13 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_elasticache
|
|
|
|
def test_describe_users_initial():
|
|
|
|
client = boto3.client("elasticache", region_name="us-east-2")
|
|
|
|
resp = client.describe_users()
|
|
|
|
|
2023-07-20 09:36:20 +00:00
|
|
|
assert len(resp["Users"]) == 1
|
|
|
|
assert resp["Users"][0] == {
|
|
|
|
"UserId": "default",
|
|
|
|
"UserName": "default",
|
|
|
|
"Status": "active",
|
|
|
|
"Engine": "redis",
|
|
|
|
"MinimumEngineVersion": "6.0",
|
|
|
|
"AccessString": "on ~* +@all",
|
|
|
|
"UserGroupIds": [],
|
|
|
|
"Authentication": {"Type": "no-password"},
|
|
|
|
"ARN": f"arn:aws:elasticache:us-east-2:{ACCOUNT_ID}:user:default",
|
|
|
|
}
|
2021-12-07 12:09:13 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_elasticache
|
|
|
|
def test_describe_users():
|
|
|
|
client = boto3.client("elasticache", region_name="ap-southeast-1")
|
|
|
|
|
|
|
|
client.create_user(
|
|
|
|
UserId="user1",
|
|
|
|
UserName="User1",
|
|
|
|
Engine="Redis",
|
|
|
|
AccessString="on ~* +@all",
|
|
|
|
Passwords=["mysecretpassthatsverylong"],
|
|
|
|
)
|
|
|
|
|
|
|
|
resp = client.describe_users()
|
|
|
|
|
2023-07-20 09:36:20 +00:00
|
|
|
assert len(resp["Users"]) == 2
|
|
|
|
assert {
|
|
|
|
"UserId": "user1",
|
|
|
|
"UserName": "User1",
|
|
|
|
"Status": "active",
|
|
|
|
"Engine": "Redis",
|
|
|
|
"MinimumEngineVersion": "6.0",
|
|
|
|
"AccessString": "on ~* +@all",
|
|
|
|
"UserGroupIds": [],
|
|
|
|
"Authentication": {"Type": "password", "PasswordCount": 1},
|
|
|
|
"ARN": f"arn:aws:elasticache:ap-southeast-1:{ACCOUNT_ID}:user:user1",
|
|
|
|
} in resp["Users"]
|
2021-12-07 12:09:13 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_elasticache
|
|
|
|
def test_describe_users_unknown_userid():
|
|
|
|
client = boto3.client("elasticache", region_name="ap-southeast-1")
|
|
|
|
|
|
|
|
with pytest.raises(ClientError) as exc:
|
|
|
|
client.describe_users(UserId="unknown")
|
|
|
|
err = exc.value.response["Error"]
|
2023-07-20 09:36:20 +00:00
|
|
|
assert err["Code"] == "UserNotFound"
|
|
|
|
assert err["Message"] == "User unknown not found."
|
2023-09-02 13:00:25 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_elasticache
|
|
|
|
def test_create_redis_cache_cluster():
|
|
|
|
client = boto3.client("elasticache", region_name="us-east-2")
|
|
|
|
|
|
|
|
test_redis_cache_cluster_exist = False
|
|
|
|
|
|
|
|
cache_cluster_id = "test-cache-cluster"
|
|
|
|
cache_cluster_engine = "redis"
|
|
|
|
cache_cluster_num_cache_nodes = 5
|
|
|
|
|
|
|
|
resp = client.create_cache_cluster(
|
|
|
|
CacheClusterId=cache_cluster_id,
|
|
|
|
Engine=cache_cluster_engine,
|
|
|
|
NumCacheNodes=cache_cluster_num_cache_nodes,
|
|
|
|
)
|
|
|
|
cache_cluster = resp["CacheCluster"]
|
|
|
|
|
|
|
|
if cache_cluster["CacheClusterId"] == cache_cluster_id:
|
|
|
|
if cache_cluster["Engine"] == cache_cluster_engine:
|
|
|
|
if cache_cluster["NumCacheNodes"] == 1:
|
|
|
|
test_redis_cache_cluster_exist = True
|
|
|
|
|
|
|
|
assert resp["ResponseMetadata"]["HTTPStatusCode"] == 200
|
|
|
|
assert test_redis_cache_cluster_exist
|
|
|
|
|
|
|
|
|
|
|
|
@mock_elasticache
|
|
|
|
def test_create_memcached_cache_cluster():
|
|
|
|
client = boto3.client("elasticache", region_name="us-east-2")
|
|
|
|
|
|
|
|
test_memcached_cache_cluster_exist = False
|
|
|
|
|
|
|
|
cache_cluster_id = "test-cache-cluster"
|
|
|
|
cache_cluster_engine = "memcached"
|
|
|
|
cache_cluster_num_cache_nodes = 5
|
|
|
|
|
|
|
|
resp = client.create_cache_cluster(
|
|
|
|
CacheClusterId=cache_cluster_id,
|
|
|
|
Engine=cache_cluster_engine,
|
|
|
|
NumCacheNodes=cache_cluster_num_cache_nodes,
|
|
|
|
)
|
|
|
|
cache_cluster = resp["CacheCluster"]
|
|
|
|
|
|
|
|
if cache_cluster["CacheClusterId"] == cache_cluster_id:
|
|
|
|
if cache_cluster["Engine"] == cache_cluster_engine:
|
|
|
|
if cache_cluster["NumCacheNodes"] == 5:
|
|
|
|
test_memcached_cache_cluster_exist = True
|
|
|
|
|
|
|
|
assert resp["ResponseMetadata"]["HTTPStatusCode"] == 200
|
|
|
|
assert test_memcached_cache_cluster_exist
|
|
|
|
|
|
|
|
|
|
|
|
@mock_elasticache
|
|
|
|
def test_create_duplicate_cache_cluster():
|
|
|
|
client = boto3.client("elasticache", region_name="us-east-2")
|
|
|
|
|
|
|
|
cache_cluster_id = "test-cache-cluster"
|
|
|
|
cache_cluster_engine = "memcached"
|
|
|
|
cache_cluster_num_cache_nodes = 5
|
|
|
|
|
|
|
|
client.create_cache_cluster(
|
|
|
|
CacheClusterId=cache_cluster_id,
|
|
|
|
Engine=cache_cluster_engine,
|
|
|
|
NumCacheNodes=cache_cluster_num_cache_nodes,
|
|
|
|
)
|
|
|
|
|
|
|
|
with pytest.raises(ClientError) as exc:
|
|
|
|
client.create_cache_cluster(
|
|
|
|
CacheClusterId=cache_cluster_id,
|
|
|
|
Engine=cache_cluster_engine,
|
|
|
|
NumCacheNodes=cache_cluster_num_cache_nodes,
|
|
|
|
)
|
|
|
|
err = exc.value.response["Error"]
|
|
|
|
assert err["Code"] == "CacheClusterAlreadyExists"
|
|
|
|
assert err["Message"] == f"Cache cluster {cache_cluster_id} already exists."
|
|
|
|
|
|
|
|
|
|
|
|
@mock_elasticache
|
|
|
|
def test_describe_all_cache_clusters():
|
|
|
|
client = boto3.client("elasticache", region_name="us-east-2")
|
|
|
|
|
|
|
|
test_memcached_cache_cluster_exist = False
|
|
|
|
|
|
|
|
cache_cluster_id = "test-cache-cluster"
|
|
|
|
cache_cluster_engine = "memcached"
|
|
|
|
cache_cluster_num_cache_nodes = 5
|
|
|
|
|
|
|
|
client.create_cache_cluster(
|
|
|
|
CacheClusterId=cache_cluster_id,
|
|
|
|
Engine=cache_cluster_engine,
|
|
|
|
NumCacheNodes=cache_cluster_num_cache_nodes,
|
|
|
|
)
|
|
|
|
|
|
|
|
resp = client.describe_cache_clusters()
|
|
|
|
|
|
|
|
cache_clusters = resp["CacheClusters"]
|
|
|
|
|
|
|
|
for cache_cluster in cache_clusters:
|
|
|
|
if cache_cluster["CacheClusterId"] == cache_cluster_id:
|
|
|
|
test_memcached_cache_cluster_exist = True
|
|
|
|
|
|
|
|
assert resp["ResponseMetadata"]["HTTPStatusCode"] == 200
|
|
|
|
assert test_memcached_cache_cluster_exist
|
|
|
|
|
|
|
|
|
|
|
|
@mock_elasticache
|
|
|
|
def test_describe_specific_cache_clusters():
|
|
|
|
client = boto3.client("elasticache", region_name="us-east-2")
|
|
|
|
|
|
|
|
test_memcached_cache_cluster_exist = False
|
|
|
|
|
|
|
|
cache_cluster_id = "test-cache-cluster"
|
|
|
|
cache_cluster_engine = "memcached"
|
|
|
|
cache_cluster_num_cache_nodes = 5
|
|
|
|
|
|
|
|
client.create_cache_cluster(
|
|
|
|
CacheClusterId=cache_cluster_id,
|
|
|
|
Engine=cache_cluster_engine,
|
|
|
|
NumCacheNodes=cache_cluster_num_cache_nodes,
|
|
|
|
)
|
|
|
|
|
|
|
|
client.create_cache_cluster(
|
|
|
|
CacheClusterId="test-cache-cluster-2",
|
|
|
|
Engine=cache_cluster_engine,
|
|
|
|
NumCacheNodes=cache_cluster_num_cache_nodes,
|
|
|
|
)
|
|
|
|
|
|
|
|
resp = client.describe_cache_clusters(CacheClusterId=cache_cluster_id)
|
|
|
|
|
|
|
|
cache_clusters = resp["CacheClusters"]
|
|
|
|
|
|
|
|
for cache_cluster in cache_clusters:
|
|
|
|
if cache_cluster["CacheClusterId"] == cache_cluster_id:
|
|
|
|
test_memcached_cache_cluster_exist = True
|
|
|
|
|
|
|
|
assert resp["ResponseMetadata"]["HTTPStatusCode"] == 200
|
|
|
|
assert test_memcached_cache_cluster_exist
|
|
|
|
|
|
|
|
|
|
|
|
@mock_elasticache
|
|
|
|
def test_describe_unknown_cache_cluster():
|
|
|
|
client = boto3.client("elasticache", region_name="us-east-2")
|
|
|
|
|
|
|
|
cache_cluster_id = "test-cache-cluster"
|
|
|
|
cache_cluster_id_unknown = "unknown-cache-cluster"
|
|
|
|
cache_cluster_engine = "memcached"
|
|
|
|
cache_cluster_num_cache_nodes = 5
|
|
|
|
|
|
|
|
client.create_cache_cluster(
|
|
|
|
CacheClusterId=cache_cluster_id,
|
|
|
|
Engine=cache_cluster_engine,
|
|
|
|
NumCacheNodes=cache_cluster_num_cache_nodes,
|
|
|
|
)
|
|
|
|
|
|
|
|
with pytest.raises(ClientError) as exc:
|
|
|
|
client.describe_cache_clusters(
|
|
|
|
CacheClusterId=cache_cluster_id_unknown,
|
|
|
|
)
|
|
|
|
err = exc.value.response["Error"]
|
|
|
|
assert err["Code"] == "CacheClusterNotFound"
|
|
|
|
assert err["Message"] == f"Cache cluster {cache_cluster_id_unknown} not found."
|
|
|
|
|
|
|
|
|
|
|
|
@mock_elasticache
|
|
|
|
def test_delete_cache_cluster():
|
|
|
|
client = boto3.client("elasticache", region_name="us-east-2")
|
|
|
|
|
|
|
|
cache_cluster_id = "test-cache-cluster"
|
|
|
|
cache_cluster_engine = "memcached"
|
|
|
|
cache_cluster_num_cache_nodes = 5
|
|
|
|
|
|
|
|
client.create_cache_cluster(
|
|
|
|
CacheClusterId=cache_cluster_id,
|
|
|
|
Engine=cache_cluster_engine,
|
|
|
|
NumCacheNodes=cache_cluster_num_cache_nodes,
|
|
|
|
)
|
|
|
|
|
|
|
|
client.delete_cache_cluster(CacheClusterId=cache_cluster_id)
|
|
|
|
|
|
|
|
resp = client.describe_cache_clusters(CacheClusterId=cache_cluster_id)
|
|
|
|
|
|
|
|
assert resp["ResponseMetadata"]["HTTPStatusCode"] == 200
|
|
|
|
assert resp["CacheClusters"][0]["CacheClusterStatus"] == "deleting"
|
|
|
|
|
|
|
|
|
|
|
|
@mock_elasticache
|
|
|
|
def test_delete_unknown_cache_cluster():
|
|
|
|
client = boto3.client("elasticache", region_name="us-east-2")
|
|
|
|
|
|
|
|
cache_cluster_id = "test-cache-cluster"
|
|
|
|
cache_cluster_id_unknown = "unknown-cache-cluster"
|
|
|
|
cache_cluster_engine = "memcached"
|
|
|
|
cache_cluster_num_cache_nodes = 5
|
|
|
|
|
|
|
|
client.create_cache_cluster(
|
|
|
|
CacheClusterId=cache_cluster_id,
|
|
|
|
Engine=cache_cluster_engine,
|
|
|
|
NumCacheNodes=cache_cluster_num_cache_nodes,
|
|
|
|
)
|
|
|
|
|
|
|
|
with pytest.raises(ClientError) as exc:
|
|
|
|
client.delete_cache_cluster(
|
|
|
|
CacheClusterId=cache_cluster_id_unknown,
|
|
|
|
)
|
|
|
|
err = exc.value.response["Error"]
|
|
|
|
assert err["Code"] == "CacheClusterNotFound"
|
|
|
|
assert err["Message"] == f"Cache cluster {cache_cluster_id_unknown} not found."
|