Skip to content

Commit bdeece4

Browse files
committed
fix: paginate messages for maildir storage
Fixes mailhog/MailHog#178
1 parent 6d871fb commit bdeece4

4 files changed

Lines changed: 108 additions & 5 deletions

File tree

maildir.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,12 +134,14 @@ func (maildir *Maildir) List(start, limit int) (*data.Messages, error) {
134134
}
135135
defer dir.Close()
136136

137-
n, err := dir.Readdir(0)
137+
files, err := dir.Readdir(0)
138138
if err != nil {
139139
return nil, err
140140
}
141+
from := minInt(start, len(files)-1)
142+
to := minInt(start+limit, len(files)-1)
141143

142-
for _, fileinfo := range n {
144+
for _, fileinfo := range files[from:to] {
143145
b, err := ioutil.ReadFile(filepath.Join(maildir.Path, fileinfo.Name()))
144146
if err != nil {
145147
return nil, err
@@ -182,3 +184,10 @@ func (maildir *Maildir) Load(id string) (*data.Message, error) {
182184
m.ID = data.MessageID(id)
183185
return m, nil
184186
}
187+
188+
func minInt(x, y int) int {
189+
if x < y {
190+
return x
191+
}
192+
return y
193+
}

maildir_test.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package storage
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func TestMaildirStore(t *testing.T) {
8+
storage := CreateMaildir("testdata")
9+
10+
if storage.Count() != 0 {
11+
t.Errorf("storage.Count() expected: %d, got: %d", 0, storage.Count())
12+
}
13+
14+
fillStorage(storage, 25)
15+
16+
if storage.Count() != 25 {
17+
t.Errorf("storage.Count() expected: %d, got: %d", 25, storage.Count())
18+
}
19+
20+
storage.DeleteAll()
21+
22+
if storage.Count() != 0 {
23+
t.Errorf("storage.Count() expected: %d, got: %d", 0, storage.Count())
24+
}
25+
}
26+
27+
func TestMaildirLoad(t *testing.T) {
28+
storage := CreateMaildir("testdata")
29+
30+
storage.Store(newMessage("123"))
31+
32+
item, err := storage.Load("123")
33+
if item == nil || err != nil {
34+
t.Errorf("storage.Load(\"123\") expected: not nil, got: nil")
35+
}
36+
37+
unexisting, err := storage.Load("321")
38+
if unexisting != nil || err == nil {
39+
t.Errorf("storage.Load(\"321\") expected: nil, got: not nil")
40+
}
41+
storage.DeleteAll()
42+
}
43+
44+
func TestMaildirList(t *testing.T) {
45+
storage := CreateMaildir("testdata")
46+
47+
fillStorage(storage, 25)
48+
49+
result, err := storage.List(0, 10)
50+
if len(*result) != 10 || err != nil {
51+
t.Errorf("len(result) expected: %d, got: %d", 10, len(*result))
52+
}
53+
54+
result, err = storage.List(20, 30)
55+
if len(*result) != 5 || err != nil {
56+
t.Errorf("len(result) expected: %d, got: %d", 5, len(*result))
57+
}
58+
storage.DeleteAll()
59+
}

memory_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99
"github.com/mailhog/data"
1010
)
1111

12-
func TestStore(t *testing.T) {
12+
func TestImMemoryStore(t *testing.T) {
1313
storage := CreateInMemory()
1414

1515
if storage.Count() != 0 {
@@ -35,7 +35,7 @@ func TestStore(t *testing.T) {
3535
}
3636
}
3737

38-
func TestDeleteAll(t *testing.T) {
38+
func TestImMemoryDeleteAll(t *testing.T) {
3939
storage := CreateInMemory()
4040

4141
if storage.Count() != 0 {
@@ -57,7 +57,7 @@ func TestDeleteAll(t *testing.T) {
5757
}
5858
}
5959

60-
func TestDeleteOne(t *testing.T) {
60+
func TestImMemoryDeleteOne(t *testing.T) {
6161
storage := CreateInMemory()
6262

6363
if storage.Count() != 0 {

storage_test.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package storage
2+
3+
import (
4+
"strconv"
5+
"sync"
6+
"time"
7+
8+
"github.com/mailhog/data"
9+
)
10+
11+
func fillStorage(storage Storage, itemsCount int) {
12+
var wg sync.WaitGroup
13+
wg.Add(itemsCount)
14+
for i := 0; i < itemsCount; i++ {
15+
go func(i int) {
16+
msg := newMessage(strconv.Itoa(i))
17+
storage.Store(msg)
18+
wg.Done()
19+
}(i)
20+
}
21+
wg.Wait()
22+
}
23+
24+
func newMessage(messageID string) *data.Message {
25+
return &data.Message{
26+
ID: data.MessageID(messageID),
27+
Created: time.Now(),
28+
Raw: &data.SMTPMessage{
29+
From: "from@email.com",
30+
To: []string{"to@email.com"},
31+
Data: "some data string",
32+
Helo: "helo string",
33+
},
34+
}
35+
}

0 commit comments

Comments
 (0)