store_sql_test.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. package chunk
  2. import (
  3. "bytes"
  4. "flag"
  5. "fmt"
  6. "github.com/flashmob/go-guerrilla/mail"
  7. "github.com/flashmob/go-guerrilla/mail/smtp"
  8. "io"
  9. "strings"
  10. "testing"
  11. "github.com/flashmob/go-guerrilla/backends"
  12. "github.com/flashmob/go-guerrilla/chunk/transfer"
  13. _ "github.com/go-sql-driver/mysql" // activate the mysql driver
  14. )
  15. // This test requires that you pass the -sql-dsn flag,
  16. // eg: go test -run ^TestSQLStore$ -sql-dsn 'user:pass@tcp(127.0.0.1:3306)/dbname?readTimeout=10s&writeTimeout=10s'
  17. var (
  18. mailTableFlag = flag.String("mail-table", "in_emails", "Table to use for testing the SQL backend")
  19. chunkTableFlag = flag.String("mail-chunk-table", "in_emails_chunks", "Table to use for testing the chunking SQL backend")
  20. sqlDSNFlag = flag.String("sql-dsn", "", "DSN to use for testing the SQL backend")
  21. sqlDriverFlag = flag.String("sql-driver", "mysql", "Driver to use for testing the SQL backend")
  22. )
  23. func TestSQLStore(t *testing.T) {
  24. if *sqlDSNFlag == "" {
  25. t.Skip("requires -sql-dsn to run")
  26. }
  27. cfg := &backends.ConfigGroup{
  28. "chunk_size": 150,
  29. "storage_engine": "sql",
  30. "compress_level": 9,
  31. "sql_driver": *sqlDriverFlag,
  32. "sql_dsn": *sqlDSNFlag,
  33. "email_table": *mailTableFlag,
  34. "email_table_chunks": *chunkTableFlag,
  35. }
  36. store, chunksaver, mimeanalyzer, stream, e, err := initTestStream(false, cfg)
  37. if err != nil {
  38. t.Error(err)
  39. return
  40. }
  41. storeSql := store.(*StoreSQL)
  42. defer func() {
  43. storeSql.zap() // purge everything from db before exiting the test
  44. }()
  45. var out bytes.Buffer
  46. buf := make([]byte, 128)
  47. if written, err := io.CopyBuffer(stream, bytes.NewBuffer([]byte(email)), buf); err != nil {
  48. t.Error(err)
  49. } else {
  50. _ = mimeanalyzer.Close()
  51. _ = chunksaver.Close()
  52. fmt.Println("written:", written)
  53. email, err := storeSql.GetMessage(e.MessageID)
  54. if err != nil {
  55. t.Error("email not found")
  56. return
  57. }
  58. // check email
  59. if email.transport != smtp.TransportType8bit {
  60. t.Error("email.transport not ", smtp.TransportType8bit.String())
  61. }
  62. if email.protocol != mail.ProtocolESMTPS {
  63. t.Error("email.protocol not ", mail.ProtocolESMTPS)
  64. }
  65. // this should read all parts
  66. r, err := NewChunkedReader(storeSql, email, 0)
  67. if w, err := io.Copy(&out, r); err != nil {
  68. t.Error(err)
  69. } else if w != email.size {
  70. t.Error("email.size != number of bytes copied from reader", w, email.size)
  71. } else if !strings.Contains(out.String(), "R0lGODlhEAA") {
  72. t.Error("The email didn't decode properly, expecting R0lGODlhEAA")
  73. }
  74. out.Reset()
  75. //return
  76. // test the seek feature
  77. r, err = NewChunkedReader(storeSql, email, 0)
  78. if err != nil {
  79. t.Error(err)
  80. t.FailNow()
  81. }
  82. // we start from 1 because if the start from 0, all the parts will be read
  83. for i := 1; i < len(email.partsInfo.Parts); i++ {
  84. fmt.Println("seeking to", i)
  85. err = r.SeekPart(i)
  86. if err != nil {
  87. t.Error(err)
  88. }
  89. w, err := io.Copy(&out, r)
  90. if err != nil {
  91. t.Error(err)
  92. }
  93. if w != int64(email.partsInfo.Parts[i-1].Size) {
  94. t.Error(i, "incorrect size, expecting", email.partsInfo.Parts[i-1].Size, "but read:", w)
  95. }
  96. out.Reset()
  97. }
  98. r, err = NewChunkedReader(storeSql, email, 0)
  99. if err != nil {
  100. t.Error(err)
  101. }
  102. part := email.partsInfo.Parts[0]
  103. encoding := transfer.QuotedPrintable
  104. if strings.Contains(part.TransferEncoding, "base") {
  105. encoding = transfer.Base64
  106. }
  107. dr, err := transfer.NewDecoder(r, encoding, part.Charset)
  108. _ = dr
  109. if err != nil {
  110. t.Error(err)
  111. t.FailNow()
  112. }
  113. //var decoded bytes.Buffer
  114. //io.Copy(&decoded, dr)
  115. //io.Copy(os.Stdout, dr)
  116. }
  117. }