mirror of https://github.com/langgenius/dify.git
[autofix.ci] apply automated fixes
This commit is contained in:
parent
c385283356
commit
6e6922c4ac
|
|
@ -50,6 +50,7 @@ class BillingDisabledPolicy(MessagesCleanPolicy):
|
|||
|
||||
No special filter logic, just return all message ids.
|
||||
"""
|
||||
|
||||
def filter_message_ids(
|
||||
self,
|
||||
messages: Sequence[SimpleMessage],
|
||||
|
|
@ -68,6 +69,7 @@ class BillingSandboxPolicy(MessagesCleanPolicy):
|
|||
- Respect grace period after subscription expiration
|
||||
- Safe default: if tenant mapping or plan is missing, do NOT delete
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
plan_provider: Callable[[Sequence[str]], dict[str, SubscriptionPlan]],
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class MessagesCleanService:
|
|||
"""
|
||||
Service for cleaning expired messages based on retention policies.
|
||||
|
||||
Compatible with non cloud edition (billing disabled): all messages in the time range will be deleted.
|
||||
Compatible with non cloud edition (billing disabled): all messages in the time range will be deleted.
|
||||
If billing is enabled: only sandbox plan tenant messages are deleted (with whitelist and grace period support).
|
||||
"""
|
||||
|
||||
|
|
@ -96,7 +96,10 @@ class MessagesCleanService:
|
|||
|
||||
logger.info(
|
||||
"clean_messages: start_from=%s, end_before=%s, batch_size=%s, policy=%s",
|
||||
start_from, end_before, batch_size, policy,
|
||||
start_from,
|
||||
end_before,
|
||||
batch_size,
|
||||
policy,
|
||||
)
|
||||
|
||||
return cls(
|
||||
|
|
@ -140,16 +143,13 @@ class MessagesCleanService:
|
|||
|
||||
logger.info(
|
||||
"clean_messages: days=%s, end_before=%s, batch_size=%s, policy=%s",
|
||||
days, end_before, batch_size, policy,
|
||||
days,
|
||||
end_before,
|
||||
batch_size,
|
||||
policy,
|
||||
)
|
||||
|
||||
return cls(
|
||||
policy=policy,
|
||||
end_before=end_before,
|
||||
start_from=None,
|
||||
batch_size=batch_size,
|
||||
dry_run=dry_run
|
||||
)
|
||||
return cls(policy=policy, end_before=end_before, start_from=None, batch_size=batch_size, dry_run=dry_run)
|
||||
|
||||
def run(self) -> dict[str, int]:
|
||||
"""
|
||||
|
|
@ -188,7 +188,9 @@ class MessagesCleanService:
|
|||
|
||||
logger.info(
|
||||
"clean_messages: start cleaning messages (dry_run=%s), start_from=%s, end_before=%s",
|
||||
self._dry_run, self._start_from, self._end_before,
|
||||
self._dry_run,
|
||||
self._start_from,
|
||||
self._end_before,
|
||||
)
|
||||
|
||||
while True:
|
||||
|
|
@ -274,7 +276,9 @@ class MessagesCleanService:
|
|||
|
||||
logger.info(
|
||||
"clean_messages (batch %s): processed %s messages, deleted %s messages",
|
||||
stats["batches"], len(messages), messages_deleted,
|
||||
stats["batches"],
|
||||
len(messages),
|
||||
messages_deleted,
|
||||
)
|
||||
else:
|
||||
# Log random sample of message IDs that would be deleted (up to 10)
|
||||
|
|
@ -283,14 +287,19 @@ class MessagesCleanService:
|
|||
|
||||
logger.info(
|
||||
"clean_messages (batch %s, dry_run): would delete %s messages, sampling %s ids:",
|
||||
stats["batches"], len(message_ids_to_delete), sample_size,
|
||||
stats["batches"],
|
||||
len(message_ids_to_delete),
|
||||
sample_size,
|
||||
)
|
||||
for msg_id in sampled_ids:
|
||||
logger.info("clean_messages (batch %s, dry_run) sample: message_id=%s", stats["batches"], msg_id)
|
||||
|
||||
logger.info(
|
||||
"clean_messages completed: total batches: %s, total messages: %s, filtered messages: %s, total deleted: %s",
|
||||
stats["batches"], stats["total_messages"], stats["filtered_messages"], stats["total_deleted"],
|
||||
stats["batches"],
|
||||
stats["total_messages"],
|
||||
stats["filtered_messages"],
|
||||
stats["total_deleted"],
|
||||
)
|
||||
|
||||
return stats
|
||||
|
|
|
|||
|
|
@ -320,7 +320,7 @@ class TestMessagesCleanServiceIntegration:
|
|||
policy = create_message_clean_policy()
|
||||
|
||||
assert isinstance(policy, BillingDisabledPolicy)
|
||||
|
||||
|
||||
service = MessagesCleanService.from_time_range(
|
||||
policy=policy,
|
||||
start_from=datetime.datetime(2024, 1, 10, 0, 0, 0),
|
||||
|
|
@ -345,9 +345,7 @@ class TestMessagesCleanServiceIntegration:
|
|||
# Related records of out-of-range message kept
|
||||
assert db.session.query(MessageFeedback).where(MessageFeedback.message_id == out_of_range_msg_id).count() == 1
|
||||
|
||||
def test_no_messages_returns_empty_stats(
|
||||
self, db_session_with_containers, mock_billing_enabled, mock_whitelist
|
||||
):
|
||||
def test_no_messages_returns_empty_stats(self, db_session_with_containers, mock_billing_enabled, mock_whitelist):
|
||||
"""Test cleaning when there are no messages to delete (B1)."""
|
||||
# Arrange
|
||||
end_before = datetime.datetime.now() - datetime.timedelta(days=30)
|
||||
|
|
@ -372,9 +370,7 @@ class TestMessagesCleanServiceIntegration:
|
|||
assert stats["filtered_messages"] == 0
|
||||
assert stats["total_deleted"] == 0
|
||||
|
||||
def test_mixed_sandbox_and_paid_tenants(
|
||||
self, db_session_with_containers, mock_billing_enabled, mock_whitelist
|
||||
):
|
||||
def test_mixed_sandbox_and_paid_tenants(self, db_session_with_containers, mock_billing_enabled, mock_whitelist):
|
||||
"""Test cleaning with mixed sandbox and paid tenants (B2)."""
|
||||
# Arrange - Create sandbox tenants with expired messages
|
||||
sandbox_tenants = []
|
||||
|
|
@ -456,9 +452,7 @@ class TestMessagesCleanServiceIntegration:
|
|||
== 0
|
||||
)
|
||||
|
||||
def test_cursor_pagination_multiple_batches(
|
||||
self, db_session_with_containers, mock_billing_enabled, mock_whitelist
|
||||
):
|
||||
def test_cursor_pagination_multiple_batches(self, db_session_with_containers, mock_billing_enabled, mock_whitelist):
|
||||
"""Test cursor pagination works correctly across multiple batches (B3)."""
|
||||
# Arrange - Create sandbox tenant with messages that will span multiple batches
|
||||
account, tenant = self._create_account_and_tenant(plan=CloudPlan.SANDBOX)
|
||||
|
|
@ -505,9 +499,7 @@ class TestMessagesCleanServiceIntegration:
|
|||
# All messages should be deleted
|
||||
assert db.session.query(Message).where(Message.id.in_(message_ids)).count() == 0
|
||||
|
||||
def test_dry_run_does_not_delete(
|
||||
self, db_session_with_containers, mock_billing_enabled, mock_whitelist
|
||||
):
|
||||
def test_dry_run_does_not_delete(self, db_session_with_containers, mock_billing_enabled, mock_whitelist):
|
||||
"""Test dry_run mode does not delete messages (B4)."""
|
||||
# Arrange
|
||||
account, tenant = self._create_account_and_tenant(plan=CloudPlan.SANDBOX)
|
||||
|
|
@ -551,9 +543,7 @@ class TestMessagesCleanServiceIntegration:
|
|||
# Related records should also still exist
|
||||
assert db.session.query(MessageFeedback).where(MessageFeedback.message_id.in_(message_ids)).count() == 3
|
||||
|
||||
def test_partial_plan_data_safe_default(
|
||||
self, db_session_with_containers, mock_billing_enabled, mock_whitelist
|
||||
):
|
||||
def test_partial_plan_data_safe_default(self, db_session_with_containers, mock_billing_enabled, mock_whitelist):
|
||||
"""Test when billing returns partial data, unknown tenants are preserved (B5)."""
|
||||
# Arrange - Create 3 tenants
|
||||
tenants_data = []
|
||||
|
|
@ -620,9 +610,7 @@ class TestMessagesCleanServiceIntegration:
|
|||
db.session.query(Message).where(Message.id == tenants_data[2]["message_id"]).count() == 1
|
||||
) # Unknown tenant's message preserved (safe default)
|
||||
|
||||
def test_empty_plan_data_skips_deletion(
|
||||
self, db_session_with_containers, mock_billing_enabled, mock_whitelist
|
||||
):
|
||||
def test_empty_plan_data_skips_deletion(self, db_session_with_containers, mock_billing_enabled, mock_whitelist):
|
||||
"""Test when billing returns empty data, skip deletion entirely (B6)."""
|
||||
# Arrange
|
||||
account, tenant = self._create_account_and_tenant(plan=CloudPlan.SANDBOX)
|
||||
|
|
@ -657,9 +645,7 @@ class TestMessagesCleanServiceIntegration:
|
|||
# Message should still exist (safe default - don't delete if plan is unknown)
|
||||
assert db.session.query(Message).where(Message.id == msg_id).count() == 1
|
||||
|
||||
def test_time_range_boundary_behavior(
|
||||
self, db_session_with_containers, mock_billing_enabled, mock_whitelist
|
||||
):
|
||||
def test_time_range_boundary_behavior(self, db_session_with_containers, mock_billing_enabled, mock_whitelist):
|
||||
"""Test that messages are correctly filtered by [start_from, end_before) time range (B7)."""
|
||||
# Arrange
|
||||
account, tenant = self._create_account_and_tenant(plan=CloudPlan.SANDBOX)
|
||||
|
|
@ -745,9 +731,7 @@ class TestMessagesCleanServiceIntegration:
|
|||
# After range, kept
|
||||
assert db.session.query(Message).where(Message.id == msg_after_id).count() == 1
|
||||
|
||||
def test_grace_period_scenarios(
|
||||
self, db_session_with_containers, mock_billing_enabled, mock_whitelist
|
||||
):
|
||||
def test_grace_period_scenarios(self, db_session_with_containers, mock_billing_enabled, mock_whitelist):
|
||||
"""Test cleaning with different graceful period scenarios (B8)."""
|
||||
# Arrange - Create 5 different tenants with different plan and expiration scenarios
|
||||
now_timestamp = int(datetime.datetime.now(datetime.UTC).timestamp())
|
||||
|
|
@ -836,9 +820,9 @@ class TestMessagesCleanServiceIntegration:
|
|||
service = MessagesCleanService.from_time_range(
|
||||
policy=policy,
|
||||
start_from=datetime.datetime.now() - datetime.timedelta(days=60),
|
||||
end_before=end_before,
|
||||
batch_size=100,
|
||||
)
|
||||
end_before=end_before,
|
||||
batch_size=100,
|
||||
)
|
||||
stats = service.run()
|
||||
|
||||
# Assert - Only messages from scenario 2 and 3 should be deleted
|
||||
|
|
@ -853,9 +837,7 @@ class TestMessagesCleanServiceIntegration:
|
|||
assert db.session.query(Message).where(Message.id == msg4_id).count() == 1 # Professional plan, kept
|
||||
assert db.session.query(Message).where(Message.id == msg5_id).count() == 1 # At boundary, kept
|
||||
|
||||
def test_tenant_whitelist(
|
||||
self, db_session_with_containers, mock_billing_enabled, mock_whitelist
|
||||
):
|
||||
def test_tenant_whitelist(self, db_session_with_containers, mock_billing_enabled, mock_whitelist):
|
||||
"""Test that whitelisted tenants' messages are not deleted (B9)."""
|
||||
# Arrange - Create 3 sandbox tenants with expired messages
|
||||
tenants_data = []
|
||||
|
|
@ -922,9 +904,7 @@ class TestMessagesCleanServiceIntegration:
|
|||
# Verify tenant2's message was deleted (not whitelisted)
|
||||
assert db.session.query(Message).where(Message.id == tenants_data[2]["message_id"]).count() == 0
|
||||
|
||||
def test_from_days_cleans_old_messages(
|
||||
self, db_session_with_containers, mock_billing_enabled, mock_whitelist
|
||||
):
|
||||
def test_from_days_cleans_old_messages(self, db_session_with_containers, mock_billing_enabled, mock_whitelist):
|
||||
"""Test from_days correctly cleans messages older than N days (B11)."""
|
||||
# Arrange
|
||||
account, tenant = self._create_account_and_tenant(plan=CloudPlan.SANDBOX)
|
||||
|
|
|
|||
Loading…
Reference in New Issue