package mailx import ( "context" "fmt" "sync" "testing" "time" "code.yun.ink/pkg/mailx/interfaces" "code.yun.ink/pkg/mailx/smtp" ) // 并发发送测试 func TestConcurrentSend(t *testing.T) { smtpClient := smtp.NewSmtp() ctx := context.Background() // 配置SMTP客户端 _, err := smtpClient.SetOption(ctx, func(opt *interfaces.Options) { opt.Smtp = &interfaces.EmailConfigDataSmtp{ Host: "smtp.example.com", Port: "587", Username: "test@example.com", Password: "password", } }) if err != nil { t.Fatalf("Failed to configure SMTP: %v", err) } // 并发测试参数 numGoroutines := 10 emailsPerGoroutine := 5 var wg sync.WaitGroup errors := make(chan error, numGoroutines*emailsPerGoroutine) start := time.Now() // 启动多个goroutine并发发送邮件 for i := 0; i < numGoroutines; i++ { wg.Add(1) go func(goroutineID int) { defer wg.Done() for j := 0; j < emailsPerGoroutine; j++ { message := interfaces.Message{ To: []string{fmt.Sprintf("test%d_%d@example.com", goroutineID, j)}, Subject: fmt.Sprintf("Concurrent Test %d-%d", goroutineID, j), Body: fmt.Sprintf("Test email from goroutine %d, email %d", goroutineID, j), } // 注意:在实际测试中,这里应该mock发送逻辑 err := smtpClient.Send(ctx, message) if err != nil { errors <- fmt.Errorf("goroutine %d, email %d: %w", goroutineID, j, err) } // 模拟发送时间 time.Sleep(10 * time.Millisecond) } }(i) } // 等待所有goroutine完成 wg.Wait() close(errors) duration := time.Since(start) totalEmails := numGoroutines * emailsPerGoroutine // 检查错误 errorCount := 0 for err := range errors { t.Logf("Error: %v", err) errorCount++ } t.Logf("Concurrent test completed:") t.Logf("- Total emails: %d", totalEmails) t.Logf("- Duration: %v", duration) t.Logf("- Errors: %d", errorCount) t.Logf("- Success rate: %.2f%%", float64(totalEmails-errorCount)/float64(totalEmails)*100) } // 内存使用测试 func TestMemoryUsage(t *testing.T) { smtpClient := smtp.NewSmtp() ctx := context.Background() _, err := smtpClient.SetOption(ctx, func(opt *interfaces.Options) { opt.Smtp = &interfaces.EmailConfigDataSmtp{ Host: "smtp.example.com", Port: "587", Username: "test@example.com", Password: "password", } }) if err != nil { t.Fatalf("Failed to configure SMTP: %v", err) } // 测试大量邮件对象创建 numEmails := 1000 messages := make([]interfaces.Message, numEmails) start := time.Now() for i := 0; i < numEmails; i++ { messages[i] = interfaces.Message{ To: []string{fmt.Sprintf("test%d@example.com", i)}, Subject: fmt.Sprintf("Memory Test %d", i), Body: fmt.Sprintf("Large email body content for testing memory usage. Email number: %d. %s", i, generateLargeContent(1024)), } } duration := time.Since(start) t.Logf("Memory test completed:") t.Logf("- Created %d email messages", numEmails) t.Logf("- Duration: %v", duration) t.Logf("- Average time per message: %v", duration/time.Duration(numEmails)) // 清理内存 messages = nil } // 连接池测试 func TestConnectionReuse(t *testing.T) { smtpClient := smtp.NewSmtp() ctx := context.Background() _, err := smtpClient.SetOption(ctx, func(opt *interfaces.Options) { opt.Smtp = &interfaces.EmailConfigDataSmtp{ Host: "smtp.example.com", Port: "587", Username: "test@example.com", Password: "password", } }) if err != nil { t.Fatalf("Failed to configure SMTP: %v", err) } // 测试多次发送是否复用连接配置 numSends := 10 start := time.Now() for i := 0; i < numSends; i++ { message := interfaces.Message{ To: []string{fmt.Sprintf("test%d@example.com", i)}, Subject: fmt.Sprintf("Connection Reuse Test %d", i), Body: "Testing connection reuse", } // 模拟发送 _ = message time.Sleep(5 * time.Millisecond) } duration := time.Since(start) t.Logf("Connection reuse test:") t.Logf("- Sent %d emails", numSends) t.Logf("- Total duration: %v", duration) t.Logf("- Average per email: %v", duration/time.Duration(numSends)) } // 错误恢复测试 func TestErrorRecovery(t *testing.T) { smtpClient := smtp.NewSmtp() ctx := context.Background() _, err := smtpClient.SetOption(ctx, func(opt *interfaces.Options) { opt.Smtp = &interfaces.EmailConfigDataSmtp{ Host: "invalid-smtp-server.com", // 故意使用无效服务器 Port: "587", Username: "test@example.com", Password: "password", } }) if err != nil { t.Fatalf("Failed to configure SMTP: %v", err) } message := interfaces.Message{ To: []string{"test@example.com"}, Subject: "Error Recovery Test", Body: "Testing error recovery mechanism", } start := time.Now() // 这应该失败并触发重试机制 err = smtpClient.Send(ctx, message) if err == nil { t.Error("Expected error for invalid SMTP server") } duration := time.Since(start) t.Logf("Error recovery test:") t.Logf("- Duration: %v", duration) t.Logf("- Expected failure with retry mechanism") } // 大附件测试 func TestLargeAttachment(t *testing.T) { // 测试大附件处理 largeContent := generateLargeContent(1024 * 1024) // 1MB message := interfaces.Message{ To: []string{"test@example.com"}, Subject: "Large Attachment Test", Body: "Testing large attachment handling", Attachment: []interfaces.Attachment{ { Content: "/tmp/large_file.txt", // 假设的大文件路径 ContentType: "text/plain", }, }, } // 验证附件大小限制 maxSize := 25 * 1024 * 1024 // 25MB if len(largeContent) > maxSize { t.Logf("Large content size: %d bytes (exceeds %d bytes limit)", len(largeContent), maxSize) } // 注意:这里不会真正发送邮件,只是测试验证逻辑 // 在实际测试中需要mock或使用测试邮件服务器 smtpClient := smtp.NewSmtp() ctx := context.Background() _, err := smtpClient.SetOption(ctx, func(opt *interfaces.Options) { opt.Smtp = &interfaces.EmailConfigDataSmtp{ Host: "smtp.example.com", Port: "587", Username: "test@example.com", Password: "password", } }) if err != nil { t.Errorf("Failed to configure SMTP: %v", err) } err = smtpClient.Send(ctx, message) if err != nil { t.Errorf("Failed to handle large attachment: %v", err) } else { t.Logf("Large attachment handled successfully") } t.Logf("Large attachment test completed") } // 压力测试 func BenchmarkEmailCreation(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { message := interfaces.Message{ To: []string{fmt.Sprintf("test%d@example.com", i)}, Subject: fmt.Sprintf("Benchmark Test %d", i), Body: "Benchmark test content", } _ = message } } // 并发基准测试 func BenchmarkConcurrentEmailCreation(b *testing.B) { b.RunParallel(func(pb *testing.PB) { i := 0 for pb.Next() { message := interfaces.Message{ To: []string{fmt.Sprintf("test%d@example.com", i)}, Subject: fmt.Sprintf("Concurrent Benchmark Test %d", i), Body: "Concurrent benchmark test content", } _ = message i++ } }) } // 配置创建基准测试 func BenchmarkSMTPConfiguration(b *testing.B) { ctx := context.Background() b.ResetTimer() for i := 0; i < b.N; i++ { smtpClient := smtp.NewSmtp() _, err := smtpClient.SetOption(ctx, func(opt *interfaces.Options) { opt.Smtp = &interfaces.EmailConfigDataSmtp{ Host: "smtp.example.com", Port: "587", Username: "test@example.com", Password: "password", } }) if err != nil { b.Fatalf("Configuration failed: %v", err) } } } // 辅助函数:生成大内容 func generateLargeContent(size int) string { content := make([]byte, size) for i := range content { content[i] = byte('A' + (i % 26)) } return string(content) } // 负载测试 func TestLoadTesting(t *testing.T) { if testing.Short() { t.Skip("Skipping load test in short mode") } smtpClient := smtp.NewSmtp() ctx := context.Background() _, err := smtpClient.SetOption(ctx, func(opt *interfaces.Options) { opt.Smtp = &interfaces.EmailConfigDataSmtp{ Host: "smtp.example.com", Port: "587", Username: "test@example.com", Password: "password", } }) if err != nil { t.Fatalf("Failed to configure SMTP: %v", err) } // 负载测试参数 totalEmails := 100 concurrency := 10 semaphore := make(chan struct{}, concurrency) var wg sync.WaitGroup start := time.Now() for i := 0; i < totalEmails; i++ { wg.Add(1) go func(emailID int) { defer wg.Done() // 获取信号量 semaphore <- struct{}{} defer func() { <-semaphore }() message := interfaces.Message{ To: []string{fmt.Sprintf("load_test_%d@example.com", emailID)}, Subject: fmt.Sprintf("Load Test Email %d", emailID), Body: fmt.Sprintf("Load testing email number %d", emailID), } // 模拟发送 time.Sleep(50 * time.Millisecond) _ = message }(i) } wg.Wait() duration := time.Since(start) t.Logf("Load test completed:") t.Logf("- Total emails: %d", totalEmails) t.Logf("- Concurrency: %d", concurrency) t.Logf("- Duration: %v", duration) t.Logf("- Throughput: %.2f emails/second", float64(totalEmails)/duration.Seconds()) }