moto/tests/test_efs/test_file_system.py

364 lines
12 KiB
Python

from __future__ import unicode_literals
import re
from os import environ
import boto3
import pytest
from botocore.exceptions import ClientError
from moto import mock_efs
from tests.test_efs.junk_drawer import has_status_code
ARN_PATT = r"^arn:(?P<Partition>[^:\n]*):(?P<Service>[^:\n]*):(?P<Region>[^:\n]*):(?P<AccountID>[^:\n]*):(?P<Ignore>(?P<ResourceType>[^:\/\n]*)[:\/])?(?P<Resource>.*)$"
STRICT_ARN_PATT = r"^arn:aws:[a-z]+:[a-z]{2}-[a-z]+-[0-9]:[0-9]+:[a-z-]+\/[a-z0-9-]+$"
SAMPLE_1_PARAMS = {
"CreationToken": "myFileSystem1",
"PerformanceMode": "generalPurpose",
"Backup": True,
"Encrypted": True,
"Tags": [{"Key": "Name", "Value": "Test Group1"}],
}
SAMPLE_2_PARAMS = {
"CreationToken": "myFileSystem2",
"PerformanceMode": "generalPurpose",
"Backup": True,
"AvailabilityZoneName": "us-west-2b",
"Encrypted": True,
"ThroughputMode": "provisioned",
"ProvisionedThroughputInMibps": 60,
"Tags": [{"Key": "Name", "Value": "Test Group1"}],
}
@pytest.fixture(scope="function")
def aws_credentials():
"""Mocked AWS Credentials for moto."""
environ["AWS_ACCESS_KEY_ID"] = "testing"
environ["AWS_SECRET_ACCESS_KEY"] = "testing"
environ["AWS_SECURITY_TOKEN"] = "testing"
environ["AWS_SESSION_TOKEN"] = "testing"
@pytest.fixture(scope="function")
def efs(aws_credentials):
with mock_efs():
yield boto3.client("efs", region_name="us-east-1")
# Testing Create
# ==============
def test_create_file_system_correct_use(efs):
from datetime import datetime
creation_token = "test_efs_create"
create_fs_resp = efs.create_file_system(
CreationToken=creation_token,
Tags=[{"Key": "Name", "Value": "Test EFS Container"}],
)
# Check the response.
assert has_status_code(create_fs_resp, 201)
assert create_fs_resp["CreationToken"] == creation_token
assert "fs-" in create_fs_resp["FileSystemId"]
assert isinstance(create_fs_resp["CreationTime"], datetime)
assert create_fs_resp["LifeCycleState"] == "available"
assert create_fs_resp["Tags"][0] == {"Key": "Name", "Value": "Test EFS Container"}
assert create_fs_resp["ThroughputMode"] == "bursting"
assert create_fs_resp["PerformanceMode"] == "generalPurpose"
assert create_fs_resp["Encrypted"] == False
assert create_fs_resp["NumberOfMountTargets"] == 0
for key_name in ["Value", "ValueInIA", "ValueInStandard"]:
assert key_name in create_fs_resp["SizeInBytes"]
assert create_fs_resp["SizeInBytes"][key_name] == 0
assert re.match(STRICT_ARN_PATT, create_fs_resp["FileSystemArn"])
# Check the (lack of the) backup policy.
with pytest.raises(ClientError) as exc_info:
efs.describe_backup_policy(FileSystemId=create_fs_resp["FileSystemId"])
resp = exc_info.value.response
assert resp["ResponseMetadata"]["HTTPStatusCode"] == 404
assert "PolicyNotFound" in resp["Error"]["Message"]
# Check the arn in detail
match_obj = re.match(ARN_PATT, create_fs_resp["FileSystemArn"])
arn_parts = match_obj.groupdict()
assert arn_parts["ResourceType"] == "file-system"
assert arn_parts["Resource"] == create_fs_resp["FileSystemId"]
assert arn_parts["Service"] == "elasticfilesystem"
assert arn_parts["AccountID"] == create_fs_resp["OwnerId"]
def test_create_file_system_aws_sample_1(efs):
resp = efs.create_file_system(**SAMPLE_1_PARAMS)
resp_metadata = resp.pop("ResponseMetadata")
assert resp_metadata["HTTPStatusCode"] == 201
assert set(resp.keys()) == {
"OwnerId",
"CreationToken",
"Encrypted",
"PerformanceMode",
"FileSystemId",
"FileSystemArn",
"CreationTime",
"LifeCycleState",
"NumberOfMountTargets",
"SizeInBytes",
"Tags",
"ThroughputMode",
}
assert resp["Tags"] == [{"Key": "Name", "Value": "Test Group1"}]
assert resp["PerformanceMode"] == "generalPurpose"
assert resp["Encrypted"]
policy_resp = efs.describe_backup_policy(FileSystemId=resp["FileSystemId"])
assert policy_resp["BackupPolicy"]["Status"] == "ENABLED"
def test_create_file_system_aws_sample_2(efs):
resp = efs.create_file_system(**SAMPLE_2_PARAMS)
resp_metadata = resp.pop("ResponseMetadata")
assert resp_metadata["HTTPStatusCode"] == 201
assert set(resp.keys()) == {
"AvailabilityZoneId",
"AvailabilityZoneName",
"PerformanceMode",
"ProvisionedThroughputInMibps",
"SizeInBytes",
"Tags",
"ThroughputMode",
"CreationTime",
"CreationToken",
"Encrypted",
"LifeCycleState",
"FileSystemId",
"FileSystemArn",
"NumberOfMountTargets",
"OwnerId",
}
assert resp["ProvisionedThroughputInMibps"] == 60
assert resp["AvailabilityZoneId"] == "usw2-az1"
assert resp["AvailabilityZoneName"] == "us-west-2b"
assert resp["ThroughputMode"] == "provisioned"
policy_resp = efs.describe_backup_policy(FileSystemId=resp["FileSystemId"])
assert policy_resp["BackupPolicy"]["Status"] == "ENABLED"
def test_create_file_system_az_name_given_backup_default(efs):
resp = efs.create_file_system(AvailabilityZoneName="us-east-1e")
policy_resp = efs.describe_backup_policy(FileSystemId=resp["FileSystemId"])
assert policy_resp["BackupPolicy"]["Status"] == "ENABLED"
def test_create_file_system_no_creation_token_given(efs):
# Note that from the API docs, it would seem this should create an error. However it
# turns out that botocore just automatically assigns a UUID.
resp = efs.create_file_system()
assert resp["ResponseMetadata"]["HTTPStatusCode"] == 201
assert "CreationToken" in resp
def test_create_file_system_file_system_already_exists(efs):
efs.create_file_system(CreationToken="foo")
with pytest.raises(ClientError) as exc_info:
efs.create_file_system(CreationToken="foo")
resp = exc_info.value.response
assert resp["ResponseMetadata"]["HTTPStatusCode"] == 409
assert "FileSystemAlreadyExists" in resp["Error"]["Message"]
# Testing Describe
# ================
def test_describe_file_systems_minimal_case(efs):
# Create the file system.
create_fs_resp = efs.create_file_system(CreationToken="foobar")
create_fs_resp.pop("ResponseMetadata")
# Describe the file systems.
desc_fs_resp = efs.describe_file_systems()
desc_fs_resp_metadata = desc_fs_resp.pop("ResponseMetadata")
assert desc_fs_resp_metadata["HTTPStatusCode"] == 200
# Check the list results.
fs_list = desc_fs_resp["FileSystems"]
assert len(fs_list) == 1
file_system = fs_list[0]
assert set(file_system.keys()) == {
"CreationTime",
"CreationToken",
"Encrypted",
"LifeCycleState",
"PerformanceMode",
"SizeInBytes",
"Tags",
"ThroughputMode",
"FileSystemId",
"FileSystemArn",
"NumberOfMountTargets",
"OwnerId",
}
assert file_system["FileSystemId"] == create_fs_resp["FileSystemId"]
# Pop out the timestamps and see if the rest of the description is the same.
create_fs_resp["SizeInBytes"].pop("Timestamp")
file_system["SizeInBytes"].pop("Timestamp")
assert file_system == create_fs_resp
def test_describe_file_systems_aws_create_sample_2(efs):
efs.create_file_system(**SAMPLE_2_PARAMS)
# Describe the file systems.
desc_resp = efs.describe_file_systems()
desc_fs_resp_metadata = desc_resp.pop("ResponseMetadata")
assert desc_fs_resp_metadata["HTTPStatusCode"] == 200
# Check the list results.
fs_list = desc_resp["FileSystems"]
assert len(fs_list) == 1
file_system = fs_list[0]
assert set(file_system.keys()) == {
"AvailabilityZoneId",
"AvailabilityZoneName",
"CreationTime",
"CreationToken",
"Encrypted",
"LifeCycleState",
"PerformanceMode",
"ProvisionedThroughputInMibps",
"SizeInBytes",
"Tags",
"ThroughputMode",
"FileSystemId",
"FileSystemArn",
"NumberOfMountTargets",
"OwnerId",
}
assert file_system["ProvisionedThroughputInMibps"] == 60
assert file_system["AvailabilityZoneId"] == "usw2-az1"
assert file_system["AvailabilityZoneName"] == "us-west-2b"
assert file_system["ThroughputMode"] == "provisioned"
def test_describe_file_systems_paging(efs):
# Create several file systems.
for i in range(10):
efs.create_file_system(CreationToken="foobar_{}".format(i))
# First call (Start)
# ------------------
# Call the tested function
resp1 = efs.describe_file_systems(MaxItems=4)
# Check the response status
assert has_status_code(resp1, 200)
# Check content of the result.
resp1.pop("ResponseMetadata")
assert set(resp1.keys()) == {"NextMarker", "FileSystems"}
assert len(resp1["FileSystems"]) == 4
fs_id_set_1 = {fs["FileSystemId"] for fs in resp1["FileSystems"]}
# Second call (Middle)
# --------------------
# Get the next marker.
resp2 = efs.describe_file_systems(MaxItems=4, Marker=resp1["NextMarker"])
# Check the response status
resp2_metadata = resp2.pop("ResponseMetadata")
assert resp2_metadata["HTTPStatusCode"] == 200
# Check the response contents.
assert set(resp2.keys()) == {"NextMarker", "FileSystems", "Marker"}
assert len(resp2["FileSystems"]) == 4
assert resp2["Marker"] == resp1["NextMarker"]
fs_id_set_2 = {fs["FileSystemId"] for fs in resp2["FileSystems"]}
assert fs_id_set_1 & fs_id_set_2 == set()
# Third call (End)
# ----------------
# Get the last marker results
resp3 = efs.describe_file_systems(MaxItems=4, Marker=resp2["NextMarker"])
# Check the response status
resp3_metadata = resp3.pop("ResponseMetadata")
assert resp3_metadata["HTTPStatusCode"] == 200
# Check the response contents.
assert set(resp3.keys()) == {"FileSystems", "Marker"}
assert len(resp3["FileSystems"]) == 2
assert resp3["Marker"] == resp2["NextMarker"]
fs_id_set_3 = {fs["FileSystemId"] for fs in resp3["FileSystems"]}
assert fs_id_set_3 & (fs_id_set_1 | fs_id_set_2) == set()
def test_describe_file_systems_invalid_marker(efs):
with pytest.raises(ClientError) as exc_info:
efs.describe_file_systems(Marker="fiddlesticks")
resp = exc_info.value.response
assert has_status_code(resp, 400)
assert "BadRequest" in resp["Error"]["Message"]
def test_describe_file_systems_invalid_creation_token(efs):
resp = efs.describe_file_systems(CreationToken="fizzle")
assert has_status_code(resp, 200)
assert len(resp["FileSystems"]) == 0
def test_describe_file_systems_invalid_file_system_id(efs):
with pytest.raises(ClientError) as exc_info:
efs.describe_file_systems(FileSystemId="fs-29879313")
resp = exc_info.value.response
assert has_status_code(resp, 404)
assert "FileSystemNotFound" in resp["Error"]["Message"]
def test_describe_file_system_creation_token_and_file_system_id(efs):
with pytest.raises(ClientError) as exc_info:
efs.describe_file_systems(CreationToken="fizzle", FileSystemId="fs-07987987")
resp = exc_info.value.response
assert has_status_code(resp, 400)
assert "BadRequest" in resp["Error"]["Message"]
# Testing Delete
# ==============
def test_delete_file_system_minimal_case(efs):
# Create the file system
resp = efs.create_file_system()
# Describe the file system, prove it shows up.
desc1 = efs.describe_file_systems()
assert len(desc1["FileSystems"]) == 1
assert resp["FileSystemId"] in {fs["FileSystemId"] for fs in desc1["FileSystems"]}
# Delete the file system.
del_resp = efs.delete_file_system(FileSystemId=resp["FileSystemId"])
assert has_status_code(del_resp, 204)
# Check that the file system is no longer there.
desc2 = efs.describe_file_systems()
assert len(desc2["FileSystems"]) == 0
def test_delete_file_system_invalid_file_system_id(efs):
with pytest.raises(ClientError) as exc_info:
efs.delete_file_system(FileSystemId="fs-2394287")
resp = exc_info.value.response
assert has_status_code(resp, 404)
assert "FileSystemNotFound" in resp["Error"]["Message"]