2022-03-19 03:36:22 +00:00
|
|
|
import time
|
2023-08-14 09:53:02 +00:00
|
|
|
|
2021-10-21 15:13:43 +00:00
|
|
|
import boto3
|
2023-08-14 09:53:02 +00:00
|
|
|
from botocore.exceptions import ClientError
|
2022-03-26 21:25:56 +00:00
|
|
|
import pytest
|
|
|
|
|
2022-02-14 20:17:48 +00:00
|
|
|
from moto import mock_timestreamwrite, settings
|
2022-08-13 09:49:43 +00:00
|
|
|
from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID
|
2021-10-21 15:13:43 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_timestreamwrite
|
|
|
|
def test_create_table():
|
|
|
|
ts = boto3.client("timestream-write", region_name="us-east-1")
|
|
|
|
ts.create_database(DatabaseName="mydatabase")
|
|
|
|
|
|
|
|
resp = ts.create_table(
|
|
|
|
DatabaseName="mydatabase",
|
|
|
|
TableName="mytable",
|
|
|
|
RetentionProperties={
|
|
|
|
"MemoryStoreRetentionPeriodInHours": 7,
|
|
|
|
"MagneticStoreRetentionPeriodInDays": 42,
|
|
|
|
},
|
|
|
|
)
|
|
|
|
table = resp["Table"]
|
2023-08-14 09:53:02 +00:00
|
|
|
assert table["Arn"] == (
|
2021-10-21 15:13:43 +00:00
|
|
|
f"arn:aws:timestream:us-east-1:{ACCOUNT_ID}:database/mydatabase/table/mytable"
|
|
|
|
)
|
2023-08-14 09:53:02 +00:00
|
|
|
assert table["TableName"] == "mytable"
|
|
|
|
assert table["DatabaseName"] == "mydatabase"
|
|
|
|
assert table["TableStatus"] == "ACTIVE"
|
|
|
|
assert table["RetentionProperties"] == {
|
|
|
|
"MemoryStoreRetentionPeriodInHours": 7,
|
|
|
|
"MagneticStoreRetentionPeriodInDays": 42,
|
|
|
|
}
|
2021-10-21 15:13:43 +00:00
|
|
|
|
|
|
|
|
2022-05-02 20:15:19 +00:00
|
|
|
@mock_timestreamwrite
|
|
|
|
def test_create_table__with_magnetic_store_write_properties():
|
|
|
|
ts = boto3.client("timestream-write", region_name="us-east-1")
|
|
|
|
ts.create_database(DatabaseName="mydatabase")
|
|
|
|
|
|
|
|
resp = ts.create_table(
|
|
|
|
DatabaseName="mydatabase",
|
|
|
|
TableName="mytable",
|
|
|
|
MagneticStoreWriteProperties={
|
|
|
|
"EnableMagneticStoreWrites": True,
|
|
|
|
"MagneticStoreRejectedDataLocation": {
|
|
|
|
"S3Configuration": {"BucketName": "hithere"}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
)
|
|
|
|
table = resp["Table"]
|
2023-08-14 09:53:02 +00:00
|
|
|
assert table["Arn"] == (
|
2022-05-02 20:15:19 +00:00
|
|
|
f"arn:aws:timestream:us-east-1:{ACCOUNT_ID}:database/mydatabase/table/mytable"
|
|
|
|
)
|
2023-08-14 09:53:02 +00:00
|
|
|
assert table["TableName"] == "mytable"
|
|
|
|
assert table["DatabaseName"] == "mydatabase"
|
|
|
|
assert table["TableStatus"] == "ACTIVE"
|
|
|
|
assert table["MagneticStoreWriteProperties"] == {
|
|
|
|
"EnableMagneticStoreWrites": True,
|
|
|
|
"MagneticStoreRejectedDataLocation": {
|
|
|
|
"S3Configuration": {"BucketName": "hithere"}
|
|
|
|
},
|
|
|
|
}
|
2022-05-02 20:15:19 +00:00
|
|
|
|
|
|
|
|
2021-10-21 15:13:43 +00:00
|
|
|
@mock_timestreamwrite
|
|
|
|
def test_create_table_without_retention_properties():
|
|
|
|
ts = boto3.client("timestream-write", region_name="us-east-1")
|
|
|
|
ts.create_database(DatabaseName="mydatabase")
|
|
|
|
|
|
|
|
resp = ts.create_table(DatabaseName="mydatabase", TableName="mytable")
|
|
|
|
table = resp["Table"]
|
2023-08-14 09:53:02 +00:00
|
|
|
assert table["Arn"] == (
|
2021-10-21 15:13:43 +00:00
|
|
|
f"arn:aws:timestream:us-east-1:{ACCOUNT_ID}:database/mydatabase/table/mytable"
|
|
|
|
)
|
2023-08-14 09:53:02 +00:00
|
|
|
assert table["TableName"] == "mytable"
|
|
|
|
assert table["DatabaseName"] == "mydatabase"
|
|
|
|
assert table["TableStatus"] == "ACTIVE"
|
|
|
|
assert table["RetentionProperties"] == {
|
|
|
|
"MemoryStoreRetentionPeriodInHours": 123,
|
|
|
|
"MagneticStoreRetentionPeriodInDays": 123,
|
|
|
|
}
|
2021-10-21 15:13:43 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_timestreamwrite
|
|
|
|
def test_describe_table():
|
|
|
|
ts = boto3.client("timestream-write", region_name="us-east-1")
|
|
|
|
ts.create_database(DatabaseName="mydatabase")
|
|
|
|
|
|
|
|
ts.create_table(
|
|
|
|
DatabaseName="mydatabase",
|
|
|
|
TableName="mytable",
|
|
|
|
RetentionProperties={
|
|
|
|
"MemoryStoreRetentionPeriodInHours": 10,
|
|
|
|
"MagneticStoreRetentionPeriodInDays": 12,
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
table = ts.describe_table(DatabaseName="mydatabase", TableName="mytable")["Table"]
|
2023-08-14 09:53:02 +00:00
|
|
|
assert table["Arn"] == (
|
2021-10-21 15:13:43 +00:00
|
|
|
f"arn:aws:timestream:us-east-1:{ACCOUNT_ID}:database/mydatabase/table/mytable"
|
|
|
|
)
|
2023-08-14 09:53:02 +00:00
|
|
|
assert table["TableName"] == "mytable"
|
|
|
|
assert table["DatabaseName"] == "mydatabase"
|
|
|
|
assert table["TableStatus"] == "ACTIVE"
|
|
|
|
assert table["RetentionProperties"] == {
|
|
|
|
"MemoryStoreRetentionPeriodInHours": 10,
|
|
|
|
"MagneticStoreRetentionPeriodInDays": 12,
|
|
|
|
}
|
2021-10-21 15:13:43 +00:00
|
|
|
|
|
|
|
|
2022-03-26 21:25:56 +00:00
|
|
|
@mock_timestreamwrite
|
|
|
|
def test_describe_unknown_database():
|
|
|
|
ts = boto3.client("timestream-write", region_name="us-east-1")
|
|
|
|
ts.create_database(DatabaseName="mydatabase")
|
|
|
|
|
|
|
|
with pytest.raises(ClientError) as exc:
|
|
|
|
ts.describe_table(DatabaseName="mydatabase", TableName="unknown")
|
|
|
|
err = exc.value.response["Error"]
|
2023-08-14 09:53:02 +00:00
|
|
|
assert err["Code"] == "ResourceNotFoundException"
|
|
|
|
assert err["Message"] == "The table unknown does not exist."
|
2022-03-26 21:25:56 +00:00
|
|
|
|
|
|
|
|
2021-10-21 15:13:43 +00:00
|
|
|
@mock_timestreamwrite
|
|
|
|
def test_create_multiple_tables():
|
|
|
|
ts = boto3.client("timestream-write", region_name="us-east-1")
|
|
|
|
ts.create_database(DatabaseName="mydatabase")
|
|
|
|
|
|
|
|
for idx in range(0, 5):
|
|
|
|
ts.create_table(
|
|
|
|
DatabaseName="mydatabase",
|
|
|
|
TableName=f"mytable_{idx}",
|
|
|
|
RetentionProperties={
|
|
|
|
"MemoryStoreRetentionPeriodInHours": 7,
|
|
|
|
"MagneticStoreRetentionPeriodInDays": 42,
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
database = ts.describe_database(DatabaseName="mydatabase")["Database"]
|
|
|
|
|
2023-08-14 09:53:02 +00:00
|
|
|
assert database["TableCount"] == 5
|
2021-10-21 15:13:43 +00:00
|
|
|
|
|
|
|
tables = ts.list_tables(DatabaseName="mydatabase")["Tables"]
|
2023-08-14 09:53:02 +00:00
|
|
|
assert len(tables) == 5
|
|
|
|
assert {t["DatabaseName"] for t in tables} == {"mydatabase"}
|
|
|
|
assert {t["TableName"] for t in tables} == {
|
|
|
|
"mytable_0",
|
|
|
|
"mytable_1",
|
|
|
|
"mytable_2",
|
|
|
|
"mytable_3",
|
|
|
|
"mytable_4",
|
|
|
|
}
|
|
|
|
assert {t["TableStatus"] for t in tables} == {"ACTIVE"}
|
2021-10-21 15:13:43 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_timestreamwrite
|
|
|
|
def test_delete_table():
|
|
|
|
ts = boto3.client("timestream-write", region_name="us-east-1")
|
|
|
|
ts.create_database(DatabaseName="mydatabase")
|
|
|
|
|
|
|
|
for idx in range(0, 3):
|
|
|
|
ts.create_table(
|
|
|
|
DatabaseName="mydatabase",
|
|
|
|
TableName=f"mytable_{idx}",
|
|
|
|
RetentionProperties={
|
|
|
|
"MemoryStoreRetentionPeriodInHours": 7,
|
|
|
|
"MagneticStoreRetentionPeriodInDays": 42,
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
tables = ts.list_tables(DatabaseName="mydatabase")["Tables"]
|
2023-08-14 09:53:02 +00:00
|
|
|
assert len(tables) == 3
|
2021-10-21 15:13:43 +00:00
|
|
|
|
|
|
|
ts.delete_table(DatabaseName="mydatabase", TableName="mytable_1")
|
|
|
|
|
|
|
|
tables = ts.list_tables(DatabaseName="mydatabase")["Tables"]
|
2023-08-14 09:53:02 +00:00
|
|
|
assert len(tables) == 2
|
|
|
|
assert {t["TableName"] for t in tables} == {"mytable_0", "mytable_2"}
|
2021-10-21 15:13:43 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_timestreamwrite
|
|
|
|
def test_update_table():
|
|
|
|
ts = boto3.client("timestream-write", region_name="us-east-1")
|
|
|
|
ts.create_database(DatabaseName="mydatabase")
|
|
|
|
ts.create_table(DatabaseName="mydatabase", TableName="mytable")
|
|
|
|
|
|
|
|
resp = ts.update_table(
|
|
|
|
DatabaseName="mydatabase",
|
|
|
|
TableName="mytable",
|
|
|
|
RetentionProperties={
|
|
|
|
"MemoryStoreRetentionPeriodInHours": 1,
|
|
|
|
"MagneticStoreRetentionPeriodInDays": 2,
|
|
|
|
},
|
|
|
|
)
|
|
|
|
table = resp["Table"]
|
2023-08-14 09:53:02 +00:00
|
|
|
assert table["RetentionProperties"] == {
|
|
|
|
"MagneticStoreRetentionPeriodInDays": 2,
|
|
|
|
"MemoryStoreRetentionPeriodInHours": 1,
|
|
|
|
}
|
2021-10-21 15:13:43 +00:00
|
|
|
|
|
|
|
table = ts.describe_table(DatabaseName="mydatabase", TableName="mytable")["Table"]
|
2023-08-14 09:53:02 +00:00
|
|
|
assert table["Arn"] == (
|
2021-10-21 15:13:43 +00:00
|
|
|
f"arn:aws:timestream:us-east-1:{ACCOUNT_ID}:database/mydatabase/table/mytable"
|
|
|
|
)
|
2023-08-14 09:53:02 +00:00
|
|
|
assert table["TableName"] == "mytable"
|
|
|
|
assert table["DatabaseName"] == "mydatabase"
|
|
|
|
assert table["TableStatus"] == "ACTIVE"
|
|
|
|
assert table["RetentionProperties"] == {
|
|
|
|
"MagneticStoreRetentionPeriodInDays": 2,
|
|
|
|
"MemoryStoreRetentionPeriodInHours": 1,
|
|
|
|
}
|
2021-10-21 15:13:43 +00:00
|
|
|
|
|
|
|
|
2022-05-02 20:15:19 +00:00
|
|
|
@mock_timestreamwrite
|
|
|
|
def test_update_table__with_magnetic_store_write_properties():
|
|
|
|
ts = boto3.client("timestream-write", region_name="us-east-1")
|
|
|
|
ts.create_database(DatabaseName="mydatabase")
|
|
|
|
|
|
|
|
ts.create_table(DatabaseName="mydatabase", TableName="mytable")
|
|
|
|
|
|
|
|
resp = ts.update_table(
|
|
|
|
DatabaseName="mydatabase",
|
|
|
|
TableName="mytable",
|
|
|
|
MagneticStoreWriteProperties={
|
|
|
|
"EnableMagneticStoreWrites": True,
|
|
|
|
"MagneticStoreRejectedDataLocation": {
|
|
|
|
"S3Configuration": {"BucketName": "hithere"}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
)
|
|
|
|
table = resp["Table"]
|
2023-08-14 09:53:02 +00:00
|
|
|
assert table["Arn"] == (
|
2022-05-02 20:15:19 +00:00
|
|
|
f"arn:aws:timestream:us-east-1:{ACCOUNT_ID}:database/mydatabase/table/mytable"
|
|
|
|
)
|
2023-08-14 09:53:02 +00:00
|
|
|
assert table["TableName"] == "mytable"
|
|
|
|
assert table["DatabaseName"] == "mydatabase"
|
|
|
|
assert table["TableStatus"] == "ACTIVE"
|
|
|
|
assert table["MagneticStoreWriteProperties"] == {
|
|
|
|
"EnableMagneticStoreWrites": True,
|
|
|
|
"MagneticStoreRejectedDataLocation": {
|
|
|
|
"S3Configuration": {"BucketName": "hithere"}
|
|
|
|
},
|
|
|
|
}
|
2022-05-02 20:15:19 +00:00
|
|
|
|
|
|
|
|
2021-10-21 15:13:43 +00:00
|
|
|
@mock_timestreamwrite
|
|
|
|
def test_write_records():
|
|
|
|
# The query-feature is not available at the moment,
|
|
|
|
# so there's no way for us to verify writing records is successful
|
|
|
|
# For now, we'll just send them off into the ether and pray
|
|
|
|
ts = boto3.client("timestream-write", region_name="us-east-1")
|
|
|
|
ts.create_database(DatabaseName="mydatabase")
|
|
|
|
ts.create_table(DatabaseName="mydatabase", TableName="mytable")
|
|
|
|
|
2023-08-14 09:53:02 +00:00
|
|
|
# Sample records from:
|
|
|
|
# https://docs.aws.amazon.com/timestream/latest/developerguide/code-samples.write.html
|
2022-03-19 03:36:22 +00:00
|
|
|
dimensions = [
|
|
|
|
{"Name": "region", "Value": "us-east-1"},
|
|
|
|
{"Name": "az", "Value": "az1"},
|
|
|
|
{"Name": "hostname", "Value": "host1"},
|
|
|
|
]
|
|
|
|
|
|
|
|
cpu_utilization = {
|
|
|
|
"Dimensions": dimensions,
|
|
|
|
"MeasureName": "cpu_utilization",
|
|
|
|
"MeasureValue": "13.5",
|
|
|
|
"MeasureValueType": "DOUBLE",
|
|
|
|
"Time": str(time.time()),
|
|
|
|
}
|
|
|
|
|
|
|
|
memory_utilization = {
|
|
|
|
"Dimensions": dimensions,
|
|
|
|
"MeasureName": "memory_utilization",
|
|
|
|
"MeasureValue": "40",
|
|
|
|
"MeasureValueType": "DOUBLE",
|
|
|
|
"Time": str(time.time()),
|
|
|
|
}
|
|
|
|
|
|
|
|
sample_records = [cpu_utilization, memory_utilization]
|
|
|
|
|
|
|
|
resp = ts.write_records(
|
2021-10-21 15:13:43 +00:00
|
|
|
DatabaseName="mydatabase",
|
|
|
|
TableName="mytable",
|
2022-03-19 03:36:22 +00:00
|
|
|
Records=sample_records,
|
|
|
|
).get("RecordsIngested", {})
|
2023-08-14 09:53:02 +00:00
|
|
|
assert resp["Total"] == len(sample_records)
|
|
|
|
assert (resp["MemoryStore"] + resp["MagneticStore"]) == resp["Total"]
|
2022-02-14 20:17:48 +00:00
|
|
|
|
|
|
|
if not settings.TEST_SERVER_MODE:
|
|
|
|
from moto.timestreamwrite.models import timestreamwrite_backends
|
|
|
|
|
2022-08-13 09:49:43 +00:00
|
|
|
backend = timestreamwrite_backends[ACCOUNT_ID]["us-east-1"]
|
2022-02-14 20:17:48 +00:00
|
|
|
records = backend.databases["mydatabase"].tables["mytable"].records
|
2023-08-14 09:53:02 +00:00
|
|
|
assert records == sample_records
|
2022-03-19 03:36:22 +00:00
|
|
|
|
|
|
|
disk_utilization = {
|
|
|
|
"Dimensions": dimensions,
|
|
|
|
"MeasureName": "disk_utilization",
|
|
|
|
"MeasureValue": "100",
|
|
|
|
"MeasureValueType": "DOUBLE",
|
|
|
|
"Time": str(time.time()),
|
|
|
|
}
|
|
|
|
sample_records.append(disk_utilization)
|
2022-02-14 20:17:48 +00:00
|
|
|
|
|
|
|
ts.write_records(
|
|
|
|
DatabaseName="mydatabase",
|
|
|
|
TableName="mytable",
|
2022-03-19 03:36:22 +00:00
|
|
|
Records=[disk_utilization],
|
2022-02-14 20:17:48 +00:00
|
|
|
)
|
2023-08-14 09:53:02 +00:00
|
|
|
assert records == sample_records
|