2018-05-17 17:24:00 +00:00
|
|
|
package mailserver
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
2018-05-21 11:30:37 +00:00
|
|
|
"github.com/stretchr/testify/require"
|
2018-05-17 17:24:00 +00:00
|
|
|
"github.com/syndtr/goleveldb/leveldb"
|
|
|
|
"github.com/syndtr/goleveldb/leveldb/storage"
|
2020-01-02 09:10:19 +00:00
|
|
|
|
|
|
|
"github.com/ethereum/go-ethereum/rlp"
|
|
|
|
|
|
|
|
"github.com/status-im/status-go/eth-node/types"
|
|
|
|
"github.com/status-im/status-go/whisper/v6"
|
2018-05-17 17:24:00 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestCleaner(t *testing.T) {
|
|
|
|
now := time.Now()
|
|
|
|
server := setupTestServer(t)
|
|
|
|
defer server.Close()
|
2020-01-08 11:12:23 +00:00
|
|
|
cleaner := newDBCleaner(server.ms.db, time.Hour)
|
2018-05-17 17:24:00 +00:00
|
|
|
|
|
|
|
archiveEnvelope(t, now.Add(-10*time.Second), server)
|
|
|
|
archiveEnvelope(t, now.Add(-3*time.Second), server)
|
|
|
|
archiveEnvelope(t, now.Add(-1*time.Second), server)
|
|
|
|
|
|
|
|
testMessagesCount(t, 3, server)
|
|
|
|
|
2020-01-08 11:12:23 +00:00
|
|
|
testPrune(t, now.Add(-5*time.Second), 1, cleaner)
|
|
|
|
testPrune(t, now.Add(-2*time.Second), 1, cleaner)
|
|
|
|
testPrune(t, now, 1, cleaner)
|
2019-01-23 13:32:45 +00:00
|
|
|
|
|
|
|
testMessagesCount(t, 0, server)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestCleanerSchedule(t *testing.T) {
|
|
|
|
now := time.Now()
|
|
|
|
server := setupTestServer(t)
|
|
|
|
defer server.Close()
|
|
|
|
|
2020-01-08 11:12:23 +00:00
|
|
|
cleaner := newDBCleaner(server.ms.db, time.Hour)
|
2019-01-23 13:32:45 +00:00
|
|
|
cleaner.period = time.Millisecond * 10
|
|
|
|
cleaner.Start()
|
|
|
|
defer cleaner.Stop()
|
|
|
|
|
|
|
|
archiveEnvelope(t, now.Add(-3*time.Hour), server)
|
|
|
|
archiveEnvelope(t, now.Add(-2*time.Hour), server)
|
|
|
|
archiveEnvelope(t, now.Add(-1*time.Minute), server)
|
|
|
|
|
|
|
|
time.Sleep(time.Millisecond * 50)
|
|
|
|
|
|
|
|
testMessagesCount(t, 1, server)
|
2018-05-17 17:24:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func benchmarkCleanerPrune(b *testing.B, messages int, batchSize int) {
|
|
|
|
t := &testing.T{}
|
|
|
|
now := time.Now()
|
|
|
|
sentTime := now.Add(-10 * time.Second)
|
|
|
|
server := setupTestServer(t)
|
|
|
|
defer server.Close()
|
|
|
|
|
2020-01-08 11:12:23 +00:00
|
|
|
cleaner := newDBCleaner(server.ms.db, time.Hour)
|
2018-05-17 17:24:00 +00:00
|
|
|
cleaner.batchSize = batchSize
|
|
|
|
|
|
|
|
for i := 0; i < messages; i++ {
|
|
|
|
archiveEnvelope(t, sentTime, server)
|
|
|
|
}
|
|
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
2020-01-08 11:12:23 +00:00
|
|
|
testPrune(t, now, 0, cleaner)
|
2018-05-17 17:24:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkCleanerPruneM100_000_B100_000(b *testing.B) {
|
|
|
|
benchmarkCleanerPrune(b, 100000, 100000)
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkCleanerPruneM100_000_B10_000(b *testing.B) {
|
|
|
|
benchmarkCleanerPrune(b, 100000, 10000)
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkCleanerPruneM100_000_B1000(b *testing.B) {
|
|
|
|
benchmarkCleanerPrune(b, 100000, 1000)
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkCleanerPruneM100_000_B100(b *testing.B) {
|
|
|
|
benchmarkCleanerPrune(b, 100000, 100)
|
|
|
|
}
|
|
|
|
|
2020-01-08 11:12:23 +00:00
|
|
|
func setupTestServer(t *testing.T) *WhisperMailServer {
|
|
|
|
var s WhisperMailServer
|
2019-05-10 10:26:57 +00:00
|
|
|
db, _ := leveldb.Open(storage.NewMemStorage(), nil)
|
|
|
|
|
2020-01-08 11:12:23 +00:00
|
|
|
s.ms = &mailServer{
|
|
|
|
db: &LevelDB{ldb: db},
|
|
|
|
adapter: &whisperAdapter{},
|
|
|
|
}
|
|
|
|
s.minRequestPoW = powRequirement
|
2018-05-17 17:24:00 +00:00
|
|
|
return &s
|
|
|
|
}
|
|
|
|
|
2020-01-08 11:12:23 +00:00
|
|
|
func archiveEnvelope(t *testing.T, sentTime time.Time, server *WhisperMailServer) *whisper.Envelope {
|
2018-05-21 11:30:37 +00:00
|
|
|
env, err := generateEnvelope(sentTime)
|
|
|
|
require.NoError(t, err)
|
2018-05-17 17:24:00 +00:00
|
|
|
server.Archive(env)
|
|
|
|
|
|
|
|
return env
|
|
|
|
}
|
|
|
|
|
2020-01-08 11:12:23 +00:00
|
|
|
func testPrune(t *testing.T, u time.Time, expected int, c *dbCleaner) {
|
2019-01-23 13:32:45 +00:00
|
|
|
n, err := c.PruneEntriesOlderThan(u)
|
2018-05-21 11:30:37 +00:00
|
|
|
require.NoError(t, err)
|
2019-01-23 13:32:45 +00:00
|
|
|
require.Equal(t, expected, n)
|
2018-05-17 17:24:00 +00:00
|
|
|
}
|
|
|
|
|
2020-01-08 11:12:23 +00:00
|
|
|
func testMessagesCount(t *testing.T, expected int, s *WhisperMailServer) {
|
|
|
|
count := countMessages(t, s.ms.db)
|
2018-05-21 11:30:37 +00:00
|
|
|
require.Equal(t, expected, count, fmt.Sprintf("expected %d message, got: %d", expected, count))
|
2018-05-17 17:24:00 +00:00
|
|
|
}
|
|
|
|
|
2019-05-13 09:25:46 +00:00
|
|
|
func countMessages(t *testing.T, db DB) int {
|
2018-05-17 17:24:00 +00:00
|
|
|
var (
|
2019-05-09 10:58:02 +00:00
|
|
|
count int
|
2019-11-23 17:57:05 +00:00
|
|
|
zero types.Hash
|
|
|
|
emptyTopic types.TopicType
|
2018-05-17 17:24:00 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
now := time.Now()
|
2019-05-09 10:58:02 +00:00
|
|
|
kl := NewDBKey(uint32(0), emptyTopic, zero)
|
|
|
|
ku := NewDBKey(uint32(now.Unix()), emptyTopic, zero)
|
2019-05-10 10:26:57 +00:00
|
|
|
|
|
|
|
query := CursorQuery{
|
|
|
|
start: kl.raw,
|
|
|
|
end: ku.raw,
|
|
|
|
}
|
|
|
|
|
2019-05-13 09:25:46 +00:00
|
|
|
i, _ := db.BuildIterator(query)
|
2020-01-21 07:11:24 +00:00
|
|
|
defer func() { _ = i.Release() }()
|
2018-05-17 17:24:00 +00:00
|
|
|
|
|
|
|
for i.Next() {
|
|
|
|
var env whisper.Envelope
|
2019-05-13 09:25:46 +00:00
|
|
|
value, err := i.GetEnvelope(query.bloom)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
err = rlp.DecodeBytes(value, &env)
|
2018-05-17 17:24:00 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
count++
|
|
|
|
}
|
|
|
|
|
|
|
|
return count
|
|
|
|
}
|