2023-02-13 20:04:05 +03:00
|
|
|
package store
|
|
|
|
|
|
|
|
import (
|
|
|
|
"archive/tar"
|
|
|
|
"archive/zip"
|
|
|
|
"bytes"
|
|
|
|
"io"
|
2023-02-14 00:37:25 +03:00
|
|
|
"io/fs"
|
2023-02-13 20:04:05 +03:00
|
|
|
"os"
|
2023-02-14 00:37:25 +03:00
|
|
|
"path/filepath"
|
2023-02-13 20:04:05 +03:00
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/mjl-/mox/mlog"
|
|
|
|
"github.com/mjl-/mox/mox-"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestExport(t *testing.T) {
|
|
|
|
// Set up an account, add 2 messages to different 2 mailboxes. export as tar/zip
|
|
|
|
// and maildir/mbox. check there are 2 files in the repo, no errors.txt.
|
|
|
|
|
|
|
|
os.RemoveAll("../testdata/store/data")
|
|
|
|
mox.ConfigStaticPath = "../testdata/store/mox.conf"
|
2023-03-06 01:56:02 +03:00
|
|
|
mox.MustLoadConfig(false)
|
2023-02-13 20:04:05 +03:00
|
|
|
acc, err := OpenAccount("mjl")
|
|
|
|
tcheck(t, err, "open account")
|
|
|
|
defer acc.Close()
|
|
|
|
switchDone := Switchboard()
|
|
|
|
defer close(switchDone)
|
|
|
|
|
|
|
|
log := mlog.New("export")
|
|
|
|
|
|
|
|
msgFile, err := os.CreateTemp("", "mox-test-export")
|
|
|
|
tcheck(t, err, "create temp")
|
|
|
|
defer os.Remove(msgFile.Name()) // To be sure.
|
|
|
|
const msg = "test: test\r\n\r\ntest\r\n"
|
|
|
|
_, err = msgFile.Write([]byte(msg))
|
|
|
|
tcheck(t, err, "write message")
|
|
|
|
|
|
|
|
m := Message{Received: time.Now(), Size: int64(len(msg))}
|
|
|
|
err = acc.DeliverMailbox(xlog, "Inbox", &m, msgFile, false)
|
|
|
|
tcheck(t, err, "deliver")
|
|
|
|
|
|
|
|
m = Message{Received: time.Now(), Size: int64(len(msg))}
|
|
|
|
err = acc.DeliverMailbox(xlog, "Trash", &m, msgFile, true)
|
|
|
|
tcheck(t, err, "deliver")
|
|
|
|
|
|
|
|
var maildirZip, maildirTar, mboxZip, mboxTar bytes.Buffer
|
|
|
|
|
|
|
|
archive := func(archiver Archiver, maildir bool) {
|
|
|
|
t.Helper()
|
2023-05-22 15:40:36 +03:00
|
|
|
err = ExportMessages(ctxbg, log, acc.DB, acc.Dir, archiver, maildir, "")
|
2023-02-13 20:04:05 +03:00
|
|
|
tcheck(t, err, "export messages")
|
|
|
|
err = archiver.Close()
|
|
|
|
tcheck(t, err, "archiver close")
|
|
|
|
}
|
|
|
|
|
2023-02-14 00:37:25 +03:00
|
|
|
os.RemoveAll("../testdata/exportmaildir")
|
|
|
|
os.RemoveAll("../testdata/exportmbox")
|
|
|
|
|
2023-02-13 20:04:05 +03:00
|
|
|
archive(ZipArchiver{zip.NewWriter(&maildirZip)}, true)
|
|
|
|
archive(ZipArchiver{zip.NewWriter(&mboxZip)}, false)
|
|
|
|
archive(TarArchiver{tar.NewWriter(&maildirTar)}, true)
|
|
|
|
archive(TarArchiver{tar.NewWriter(&mboxTar)}, false)
|
2023-02-14 00:37:25 +03:00
|
|
|
archive(DirArchiver{"../testdata/exportmaildir"}, true)
|
|
|
|
archive(DirArchiver{"../testdata/exportmbox"}, false)
|
2023-02-13 20:04:05 +03:00
|
|
|
|
|
|
|
if r, err := zip.NewReader(bytes.NewReader(maildirZip.Bytes()), int64(maildirZip.Len())); err != nil {
|
|
|
|
t.Fatalf("reading maildir zip: %v", err)
|
|
|
|
} else if len(r.File) != 2*3+2 {
|
|
|
|
t.Fatalf("maildir zip, expected 2*3 dirs, and 2 files, got %d files", len(r.File))
|
|
|
|
}
|
|
|
|
|
|
|
|
if r, err := zip.NewReader(bytes.NewReader(mboxZip.Bytes()), int64(mboxZip.Len())); err != nil {
|
|
|
|
t.Fatalf("reading mbox zip: %v", err)
|
|
|
|
} else if len(r.File) != 2 {
|
|
|
|
t.Fatalf("maildir zip, 2 files, got %d files", len(r.File))
|
|
|
|
}
|
|
|
|
|
|
|
|
checkTarFiles := func(r io.Reader, n int) {
|
|
|
|
t.Helper()
|
|
|
|
tr := tar.NewReader(r)
|
|
|
|
have := 0
|
|
|
|
for {
|
|
|
|
h, err := tr.Next()
|
|
|
|
if err == io.EOF {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
have++
|
|
|
|
if h.Name == "errors.txt" {
|
|
|
|
t.Fatalf("got errors.txt")
|
|
|
|
}
|
|
|
|
_, err = io.Copy(io.Discard, tr)
|
|
|
|
tcheck(t, err, "copy")
|
|
|
|
}
|
2023-02-14 00:37:25 +03:00
|
|
|
if have != n {
|
|
|
|
t.Fatalf("got %d files, expected %d", have, n)
|
2023-02-13 20:04:05 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
checkTarFiles(&maildirTar, 2*3+2)
|
|
|
|
checkTarFiles(&mboxTar, 2)
|
2023-02-14 00:37:25 +03:00
|
|
|
|
|
|
|
checkDirFiles := func(dir string, n int) {
|
|
|
|
t.Helper()
|
|
|
|
have := 0
|
|
|
|
err := filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error {
|
|
|
|
if err == nil && !d.IsDir() {
|
|
|
|
have++
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
tcheck(t, err, "walkdir")
|
|
|
|
if n != have {
|
|
|
|
t.Fatalf("got %d files, expected %d", have, n)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
checkDirFiles("../testdata/exportmaildir", 2)
|
|
|
|
checkDirFiles("../testdata/exportmbox", 2)
|
2023-02-13 20:04:05 +03:00
|
|
|
}
|