ops_scheduled_report_service_test.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. package service
  2. import (
  3. "context"
  4. "testing"
  5. "time"
  6. "github.com/stretchr/testify/require"
  7. )
  8. func TestOpsSummaryReportEmailVariables(t *testing.T) {
  9. latencyP50 := 8231
  10. latencyP99 := 151260
  11. ttftP50 := 1674
  12. ttftP99 := 11222
  13. now := time.Date(2026, time.July, 19, 1, 0, 26, 0, time.UTC)
  14. report := &opsScheduledReport{
  15. Name: "日报",
  16. ReportType: "daily_summary",
  17. TimeRange: 24 * time.Hour,
  18. }
  19. overview := &OpsDashboardOverview{
  20. RequestCountTotal: 2374,
  21. SuccessCount: 1451,
  22. ErrorCountSLA: 2,
  23. BusinessLimitedCount: 921,
  24. SLA: 0.9986,
  25. ErrorRate: 0.0014,
  26. UpstreamErrorRate: 0.0028,
  27. UpstreamErrorCountExcl429529: 4,
  28. Upstream429Count: 0,
  29. Upstream529Count: 0,
  30. TokenConsumed: 121550190,
  31. Duration: OpsPercentiles{P50: &latencyP50, P99: &latencyP99},
  32. TTFT: OpsPercentiles{P50: &ttftP50, P99: &ttftP99},
  33. QPS: OpsRateSummary{Current: 0, Peak: 1.2, Avg: 0},
  34. TPS: OpsRateSummary{Current: 0, Peak: 133421.2, Avg: 1406.8},
  35. }
  36. variables := opsSummaryReportEmailVariables(report, now, overview, "en")
  37. require.Equal(t, "Daily summary", variables["report_name"])
  38. require.Equal(t, "daily_summary", variables["report_type"])
  39. require.Equal(t, "2026-07-18T01:00:26Z", variables["report_start_time"])
  40. require.Equal(t, "2026-07-19T01:00:26Z", variables["report_end_time"])
  41. require.Equal(t, "2,374", variables["report_total_requests"])
  42. require.Equal(t, "1,451", variables["report_success_count"])
  43. require.Equal(t, "2", variables["report_sla_error_count"])
  44. require.Equal(t, "921", variables["report_business_limited_count"])
  45. require.Equal(t, "99.86%", variables["report_sla"])
  46. require.Equal(t, "0.14%", variables["report_error_rate"])
  47. require.Equal(t, "0.28%", variables["report_upstream_error_rate"])
  48. require.Equal(t, "4", variables["report_upstream_error_count_excl_429_529"])
  49. require.Equal(t, "8,231 ms", variables["report_latency_p50"])
  50. require.Equal(t, "151,260 ms", variables["report_latency_p99"])
  51. require.Equal(t, "1,674 ms", variables["report_ttft_p50"])
  52. require.Equal(t, "11,222 ms", variables["report_ttft_p99"])
  53. require.Equal(t, "121,550,190", variables["report_tokens"])
  54. require.Equal(t, "1.2", variables["report_qps_peak"])
  55. require.Equal(t, "133421.2", variables["report_tps_peak"])
  56. require.Equal(t, "1406.8", variables["report_tps_avg"])
  57. require.Empty(t, variables["report_html"])
  58. require.Equal(t, "none", variables["report_detail_display"])
  59. zhVariables := opsSummaryReportEmailVariables(report, now, overview, "zh-CN")
  60. require.Equal(t, "日报", zhVariables["report_name"])
  61. emptyVariables := opsSummaryReportEmailVariables(report, now, nil, "en")
  62. require.Equal(t, "block", emptyVariables["report_summary_display"])
  63. require.Equal(t, "none", emptyVariables["report_detail_display"])
  64. legacyTemplate, err := renderNotificationEmail(
  65. NotificationEmailEventOpsScheduledReport,
  66. "Report",
  67. `<section>{{report_html}}</section>`,
  68. variables,
  69. map[string]string{"report_html": `<h2>generated summary</h2>`},
  70. )
  71. require.NoError(t, err)
  72. require.Contains(t, legacyTemplate.HTML, `<h2>generated summary</h2>`)
  73. }
  74. func TestOpsScheduledReportVariablesDoNotUsePreviewMetrics(t *testing.T) {
  75. now := time.Date(2026, time.July, 19, 1, 0, 26, 0, time.UTC)
  76. report := &opsScheduledReport{
  77. Name: "错误摘要",
  78. ReportType: "error_digest",
  79. TimeRange: 24 * time.Hour,
  80. }
  81. variables := opsScheduledReportLocalizedEmailVariables(report, now, "en")
  82. require.Equal(t, "Error digest", variables["report_name"])
  83. require.Empty(t, variables["report_html"])
  84. require.Equal(t, "block", variables["report_detail_display"])
  85. for _, placeholder := range notificationEmailOpsSummaryPlaceholders {
  86. if placeholder == "report_summary_display" {
  87. require.Equal(t, "none", variables[placeholder])
  88. continue
  89. }
  90. require.Equal(t, "-", variables[placeholder])
  91. }
  92. }
  93. func TestOpsScheduledReportLegacyTemplateReceivesSummaryHTML(t *testing.T) {
  94. ctx := context.Background()
  95. repo := newNotificationEmailMemorySettingRepo()
  96. smtpServer := startNotificationEmailTestSMTPServer(t)
  97. require.NoError(t, repo.SetMultiple(ctx, smtpServer.settings()))
  98. emailService := NewEmailService(repo, nil)
  99. notificationService := NewNotificationEmailService(repo, emailService)
  100. _, err := notificationService.UpdateTemplate(
  101. ctx,
  102. NotificationEmailEventOpsScheduledReport,
  103. "en",
  104. "Legacy report {{report_name}}",
  105. `<section data-template="legacy">{{report_html}}</section>`,
  106. )
  107. require.NoError(t, err)
  108. svc := &OpsScheduledReportService{
  109. opsService: &OpsService{opsRepo: &opsRepoMock{}},
  110. emailService: emailService,
  111. }
  112. report := &opsScheduledReport{
  113. Name: "日报",
  114. ReportType: "daily_summary",
  115. TimeRange: 24 * time.Hour,
  116. Recipients: []string{"ops@example.com"},
  117. }
  118. attempts, err := svc.runReport(ctx, report, time.Date(2026, time.July, 19, 1, 0, 26, 0, time.UTC))
  119. require.NoError(t, err)
  120. require.Equal(t, 1, attempts)
  121. require.Equal(t, int64(1), smtpServer.messageCount())
  122. messageBody := smtpServer.lastMessageBody(t)
  123. require.Contains(t, messageBody, `<section data-template="legacy">`)
  124. require.Contains(t, messageBody, `<h2>日报</h2>`)
  125. }
  126. func TestFormatOpsReportIntegerGroupsDigits(t *testing.T) {
  127. require.Equal(t, "2,374", formatOpsReportInteger(2374))
  128. require.Equal(t, "-1,234", formatOpsReportInteger(-1234))
  129. require.Equal(t, "42", formatOpsReportInteger(42))
  130. }