github.com/status-im/status-go@v1.1.0/mailserver/cleaner_test.go (about) 1 package mailserver 2 3 import ( 4 "fmt" 5 "testing" 6 "time" 7 8 "github.com/stretchr/testify/require" 9 "github.com/syndtr/goleveldb/leveldb" 10 "github.com/syndtr/goleveldb/leveldb/storage" 11 12 "github.com/ethereum/go-ethereum/rlp" 13 14 "github.com/status-im/status-go/eth-node/types" 15 waku "github.com/status-im/status-go/waku/common" 16 ) 17 18 func TestCleaner(t *testing.T) { 19 now := time.Now() 20 server := setupTestServer(t) 21 defer server.Close() 22 cleaner := newDBCleaner(server.ms.db, time.Hour) 23 24 archiveEnvelope(t, now.Add(-10*time.Second), server) 25 archiveEnvelope(t, now.Add(-3*time.Second), server) 26 archiveEnvelope(t, now.Add(-1*time.Second), server) 27 28 testMessagesCount(t, 3, server) 29 30 testPrune(t, now.Add(-5*time.Second), 1, cleaner) 31 testPrune(t, now.Add(-2*time.Second), 1, cleaner) 32 testPrune(t, now, 1, cleaner) 33 34 testMessagesCount(t, 0, server) 35 } 36 37 func TestCleanerSchedule(t *testing.T) { 38 now := time.Now() 39 server := setupTestServer(t) 40 defer server.Close() 41 42 cleaner := newDBCleaner(server.ms.db, time.Hour) 43 cleaner.period = time.Millisecond * 10 44 cleaner.Start() 45 defer cleaner.Stop() 46 47 archiveEnvelope(t, now.Add(-3*time.Hour), server) 48 archiveEnvelope(t, now.Add(-2*time.Hour), server) 49 archiveEnvelope(t, now.Add(-1*time.Minute), server) 50 51 time.Sleep(time.Millisecond * 50) 52 53 testMessagesCount(t, 1, server) 54 } 55 56 func benchmarkCleanerPrune(b *testing.B, messages int, batchSize int) { 57 t := &testing.T{} 58 now := time.Now() 59 sentTime := now.Add(-10 * time.Second) 60 server := setupTestServer(t) 61 defer server.Close() 62 63 cleaner := newDBCleaner(server.ms.db, time.Hour) 64 cleaner.batchSize = batchSize 65 66 for i := 0; i < messages; i++ { 67 archiveEnvelope(t, sentTime, server) 68 } 69 70 for i := 0; i < b.N; i++ { 71 testPrune(t, now, 0, cleaner) 72 } 73 } 74 75 func BenchmarkCleanerPruneM100_000_B100_000(b *testing.B) { 76 benchmarkCleanerPrune(b, 100000, 100000) 77 } 78 79 func BenchmarkCleanerPruneM100_000_B10_000(b *testing.B) { 80 benchmarkCleanerPrune(b, 100000, 10000) 81 } 82 83 func BenchmarkCleanerPruneM100_000_B1000(b *testing.B) { 84 benchmarkCleanerPrune(b, 100000, 1000) 85 } 86 87 func BenchmarkCleanerPruneM100_000_B100(b *testing.B) { 88 benchmarkCleanerPrune(b, 100000, 100) 89 } 90 91 func setupTestServer(t *testing.T) *WakuMailServer { 92 var s WakuMailServer 93 db, _ := leveldb.Open(storage.NewMemStorage(), nil) 94 95 s.ms = &mailServer{ 96 db: &LevelDB{ 97 ldb: db, 98 done: make(chan struct{}), 99 }, 100 adapter: &wakuAdapter{}, 101 } 102 s.minRequestPoW = powRequirement 103 return &s 104 } 105 106 func archiveEnvelope(t *testing.T, sentTime time.Time, server *WakuMailServer) *waku.Envelope { 107 env, err := generateEnvelope(sentTime) 108 require.NoError(t, err) 109 server.Archive(env) 110 111 return env 112 } 113 114 func testPrune(t *testing.T, u time.Time, expected int, c *dbCleaner) { 115 n, err := c.PruneEntriesOlderThan(u) 116 require.NoError(t, err) 117 require.Equal(t, expected, n) 118 } 119 120 func testMessagesCount(t *testing.T, expected int, s *WakuMailServer) { 121 count := countMessages(t, s.ms.db) 122 require.Equal(t, expected, count, fmt.Sprintf("expected %d message, got: %d", expected, count)) 123 } 124 125 func countMessages(t *testing.T, db DB) int { 126 var ( 127 count int 128 zero types.Hash 129 emptyTopic types.TopicType 130 ) 131 132 now := time.Now() 133 kl := NewDBKey(uint32(0), emptyTopic, zero) 134 ku := NewDBKey(uint32(now.Unix()), emptyTopic, zero) 135 136 query := CursorQuery{ 137 start: kl.raw, 138 end: ku.raw, 139 } 140 141 i, _ := db.BuildIterator(query) 142 defer func() { _ = i.Release() }() 143 144 for i.Next() { 145 var env waku.Envelope 146 value, err := i.GetEnvelopeByBloomFilter(query.bloom) 147 if err != nil { 148 t.Fatal(err) 149 } 150 151 err = rlp.DecodeBytes(value, &env) 152 if err != nil { 153 t.Fatal(err) 154 } 155 156 count++ 157 } 158 159 return count 160 }