cache_test.go

  1package config
  2
  3import (
  4	"reflect"
  5	"strings"
  6	"testing"
  7	"time"
  8)
  9
 10func TestSaveEmailBodyEvictsLeastRecentlyAccessedAcrossFolders(t *testing.T) {
 11	folderCacheTestSetup(t)
 12
 13	oldTime := time.Now().Add(-2 * time.Hour)
 14	recentTime := time.Now().Add(-1 * time.Hour)
 15
 16	if err := saveEmailBodyCache(&EmailBodyCache{
 17		FolderName: "INBOX",
 18		Bodies: []CachedEmailBody{
 19			{
 20				UID:            1,
 21				AccountID:      "acct",
 22				Body:           strings.Repeat("a", 10),
 23				SizeBytes:      10,
 24				CachedAt:       oldTime,
 25				LastAccessedAt: oldTime,
 26			},
 27		},
 28	}); err != nil {
 29		t.Fatalf("save old cache: %v", err)
 30	}
 31
 32	if err := saveEmailBodyCache(&EmailBodyCache{
 33		FolderName: "Archive",
 34		Bodies: []CachedEmailBody{
 35			{
 36				UID:            2,
 37				AccountID:      "acct",
 38				Body:           strings.Repeat("b", 10),
 39				SizeBytes:      10,
 40				CachedAt:       recentTime,
 41				LastAccessedAt: recentTime,
 42			},
 43		},
 44	}); err != nil {
 45		t.Fatalf("save recent cache: %v", err)
 46	}
 47
 48	if err := SaveEmailBody("Sent", CachedEmailBody{
 49		UID:       3,
 50		AccountID: "acct",
 51		Body:      strings.Repeat("c", 10),
 52	}, 20); err != nil {
 53		t.Fatalf("SaveEmailBody: %v", err)
 54	}
 55
 56	inbox, err := LoadEmailBodyCache("INBOX")
 57	if err != nil {
 58		t.Fatalf("LoadEmailBodyCache(INBOX): %v", err)
 59	}
 60	if len(inbox.Bodies) != 0 {
 61		t.Fatalf("oldest INBOX body should be evicted, got %d bodies", len(inbox.Bodies))
 62	}
 63
 64	archive, err := LoadEmailBodyCache("Archive")
 65	if err != nil {
 66		t.Fatalf("LoadEmailBodyCache(Archive): %v", err)
 67	}
 68	if len(archive.Bodies) != 1 || archive.Bodies[0].UID != 2 {
 69		t.Fatalf("recent Archive body should remain, got %+v", archive.Bodies)
 70	}
 71
 72	sent, err := LoadEmailBodyCache("Sent")
 73	if err != nil {
 74		t.Fatalf("LoadEmailBodyCache(Sent): %v", err)
 75	}
 76	if len(sent.Bodies) != 1 || sent.Bodies[0].UID != 3 {
 77		t.Fatalf("new Sent body should remain, got %+v", sent.Bodies)
 78	}
 79}
 80
 81func TestSaveEmailBodyEvictsMultipleEntriesUntilUnderLimit(t *testing.T) {
 82	folderCacheTestSetup(t)
 83
 84	now := time.Now()
 85	bodies := make([]CachedEmailBody, 0, 4)
 86	for i := 1; i <= 4; i++ {
 87		accessedAt := now.Add(-time.Duration(5-i) * time.Minute)
 88		bodies = append(bodies, CachedEmailBody{
 89			UID:            uint32(i),
 90			AccountID:      "acct",
 91			Body:           strings.Repeat(string(rune('a'+i-1)), 10),
 92			SizeBytes:      10,
 93			CachedAt:       accessedAt,
 94			LastAccessedAt: accessedAt,
 95		})
 96	}
 97
 98	if err := saveEmailBodyCache(&EmailBodyCache{
 99		FolderName: "INBOX",
100		Bodies:     bodies,
101	}); err != nil {
102		t.Fatalf("save cache: %v", err)
103	}
104
105	if err := SaveEmailBody("Archive", CachedEmailBody{
106		UID:       5,
107		AccountID: "acct",
108		Body:      strings.Repeat("e", 30),
109	}, 50); err != nil {
110		t.Fatalf("SaveEmailBody: %v", err)
111	}
112
113	inbox, err := LoadEmailBodyCache("INBOX")
114	if err != nil {
115		t.Fatalf("LoadEmailBodyCache(INBOX): %v", err)
116	}
117
118	gotUIDs := make([]uint32, 0, len(inbox.Bodies))
119	for _, body := range inbox.Bodies {
120		gotUIDs = append(gotUIDs, body.UID)
121	}
122	wantUIDs := []uint32{3, 4}
123	if !reflect.DeepEqual(gotUIDs, wantUIDs) {
124		t.Fatalf("remaining INBOX UIDs = %v, want %v", gotUIDs, wantUIDs)
125	}
126
127	archive, err := LoadEmailBodyCache("Archive")
128	if err != nil {
129		t.Fatalf("LoadEmailBodyCache(Archive): %v", err)
130	}
131	if len(archive.Bodies) != 1 || archive.Bodies[0].UID != 5 {
132		t.Fatalf("new Archive body should remain, got %+v", archive.Bodies)
133	}
134}
135
136func TestSaveEmailBodyDropsOversizedReplacement(t *testing.T) {
137	folderCacheTestSetup(t)
138
139	if err := SaveEmailBody("INBOX", CachedEmailBody{
140		UID:       1,
141		AccountID: "acct",
142		Body:      strings.Repeat("a", 10),
143	}, 20); err != nil {
144		t.Fatalf("initial SaveEmailBody: %v", err)
145	}
146
147	if err := SaveEmailBody("INBOX", CachedEmailBody{
148		UID:       1,
149		AccountID: "acct",
150		Body:      strings.Repeat("b", 25),
151	}, 20); err != nil {
152		t.Fatalf("oversized SaveEmailBody: %v", err)
153	}
154
155	cache, err := LoadEmailBodyCache("INBOX")
156	if err != nil {
157		t.Fatalf("LoadEmailBodyCache: %v", err)
158	}
159	if len(cache.Bodies) != 0 {
160		t.Fatalf("oversized replacement should not remain cached, got %+v", cache.Bodies)
161	}
162}