feat: add integration tests and seed script for Azure Storage emulator
- scripts/seed_test_data.py: seeds 45 orders (30 Recived + 15 Payed) across 5 users and 3 days into the emulator - tests/test_integration.py: full pipeline test (seed → scan → backup → delete) with table cleanup before/after - pytest marker "integration" to separate from unit tests Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
115
scripts/seed_test_data.py
Normal file
115
scripts/seed_test_data.py
Normal file
@@ -0,0 +1,115 @@
|
||||
"""Seed test data into Azure Table emulator for integration testing."""
|
||||
|
||||
import sys
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from azure.data.tables import TableServiceClient
|
||||
|
||||
DEFAULT_CONNECTION_STRING = (
|
||||
"AccountName=devstoreaccount1;"
|
||||
"AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/"
|
||||
"K1SZFPTOtr/KBHBeksoGMGw==;"
|
||||
"DefaultEndpointsProtocol=http;"
|
||||
"BlobEndpoint=http://192.168.9.101:10000/devstoreaccount1;"
|
||||
"QueueEndpoint=http://192.168.9.101:10001/devstoreaccount1;"
|
||||
"TableEndpoint=http://192.168.9.101:10002/devstoreaccount1;"
|
||||
)
|
||||
|
||||
TABLE_NAME = "order"
|
||||
|
||||
# Test users
|
||||
USERS = ["user001", "user002", "user003", "user004", "user005"]
|
||||
|
||||
# 3 days of data: Jan 1-3, 2025
|
||||
DATES = [
|
||||
datetime(2025, 1, 1, tzinfo=timezone.utc),
|
||||
datetime(2025, 1, 2, tzinfo=timezone.utc),
|
||||
datetime(2025, 1, 3, tzinfo=timezone.utc),
|
||||
]
|
||||
|
||||
|
||||
def seed(connection_string: str) -> None:
|
||||
service = TableServiceClient.from_connection_string(connection_string)
|
||||
service.create_table_if_not_exists(table_name=TABLE_NAME)
|
||||
client = service.get_table_client(table_name=TABLE_NAME)
|
||||
|
||||
# Clear existing data
|
||||
existing = list(client.list_entities(select=["PartitionKey", "RowKey"]))
|
||||
by_partition: dict[str, list[dict]] = {}
|
||||
for e in existing:
|
||||
pk = e["PartitionKey"]
|
||||
by_partition.setdefault(pk, []).append(
|
||||
{"PartitionKey": pk, "RowKey": e["RowKey"]}
|
||||
)
|
||||
for pk, entities in by_partition.items():
|
||||
for i in range(0, len(entities), 100):
|
||||
batch = entities[i : i + 100]
|
||||
ops = [("delete", e) for e in batch]
|
||||
client.submit_transaction(ops)
|
||||
if existing:
|
||||
print(f"Cleared {len(existing)} existing records")
|
||||
|
||||
# Seed new data
|
||||
entities = []
|
||||
order_idx = 0
|
||||
for date in DATES:
|
||||
for user in USERS:
|
||||
# 2 Recived orders per user per day
|
||||
for _ in range(2):
|
||||
hour = 8 + (order_idx % 12)
|
||||
entities.append({
|
||||
"PartitionKey": user,
|
||||
"RowKey": f"test-order-{order_idx:04d}",
|
||||
"OrderTime": date.replace(hour=hour, minute=order_idx % 60),
|
||||
"ReceiveTime": date.replace(hour=hour + 1, minute=order_idx % 60),
|
||||
"revenue": 10.0 + order_idx,
|
||||
"platformOrder": f"plat-{order_idx:04d}",
|
||||
"prodCount": 1 + (order_idx % 5),
|
||||
"pfId": user,
|
||||
"prodId": f"prod-{order_idx % 3}",
|
||||
"prodPrice": 10.0 + (order_idx % 10),
|
||||
"state": 1, # Recived
|
||||
"ver": 3,
|
||||
"customData": None,
|
||||
})
|
||||
order_idx += 1
|
||||
|
||||
# 1 Payed order per user per day (should be skipped by backup)
|
||||
entities.append({
|
||||
"PartitionKey": user,
|
||||
"RowKey": f"test-order-{order_idx:04d}",
|
||||
"OrderTime": date.replace(hour=14, minute=30),
|
||||
"ReceiveTime": None,
|
||||
"revenue": 5.0,
|
||||
"platformOrder": f"plat-payed-{order_idx:04d}",
|
||||
"prodCount": 1,
|
||||
"pfId": user,
|
||||
"prodId": "prod-pay",
|
||||
"prodPrice": 5.0,
|
||||
"state": 0, # Payed
|
||||
"ver": 3,
|
||||
"customData": None,
|
||||
})
|
||||
order_idx += 1
|
||||
|
||||
# Insert in batches grouped by PartitionKey
|
||||
total = 0
|
||||
by_pk: dict[str, list[dict]] = {}
|
||||
for e in entities:
|
||||
by_pk.setdefault(e["PartitionKey"], []).append(e)
|
||||
|
||||
for pk, pk_entities in by_pk.items():
|
||||
for i in range(0, len(pk_entities), 100):
|
||||
batch = pk_entities[i : i + 100]
|
||||
ops = [("create", e) for e in batch]
|
||||
client.submit_transaction(ops)
|
||||
total += len(batch)
|
||||
|
||||
print(f"Seeded {total} orders across {len(by_pk)} partitions, {len(DATES)} days")
|
||||
print(f" Recived (state=1): {len([e for e in entities if e['state'] == 1])}")
|
||||
print(f" Payed (state=0): {len([e for e in entities if e['state'] == 0])}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
conn_str = sys.argv[1] if len(sys.argv) > 1 else DEFAULT_CONNECTION_STRING
|
||||
seed(conn_str)
|
||||
Reference in New Issue
Block a user