mirror of https://github.com/etcd-io/bbolt.git
117 lines
2.4 KiB
Go
117 lines
2.4 KiB
Go
//go:build !windows
|
|
// +build !windows
|
|
|
|
package bbolt_test
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
|
|
"golang.org/x/sys/unix"
|
|
|
|
bolt "go.etcd.io/bbolt"
|
|
"go.etcd.io/bbolt/internal/btesting"
|
|
)
|
|
|
|
func TestMlock_DbOpen(t *testing.T) {
|
|
// 32KB
|
|
skipOnMemlockLimitBelow(t, 32*1024)
|
|
|
|
btesting.MustCreateDBWithOption(t, &bolt.Options{Mlock: true})
|
|
}
|
|
|
|
// Test change between "empty" (16KB) and "non-empty" db
|
|
func TestMlock_DbCanGrow_Small(t *testing.T) {
|
|
// 32KB
|
|
skipOnMemlockLimitBelow(t, 32*1024)
|
|
|
|
db := btesting.MustCreateDBWithOption(t, &bolt.Options{Mlock: true})
|
|
|
|
if err := db.Update(func(tx *bolt.Tx) error {
|
|
b, err := tx.CreateBucketIfNotExists([]byte("bucket"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
key := []byte("key")
|
|
value := []byte("value")
|
|
if err := b.Put(key, value); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
return nil
|
|
}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
}
|
|
|
|
// Test crossing of 16MB (AllocSize) of db size
|
|
func TestMlock_DbCanGrow_Big(t *testing.T) {
|
|
if testing.Short() {
|
|
t.Skip("skipping test in short mode")
|
|
}
|
|
|
|
// 32MB
|
|
skipOnMemlockLimitBelow(t, 32*1024*1024)
|
|
|
|
chunksBefore := 64
|
|
chunksAfter := 64
|
|
|
|
db := btesting.MustCreateDBWithOption(t, &bolt.Options{Mlock: true})
|
|
|
|
for chunk := 0; chunk < chunksBefore; chunk++ {
|
|
insertChunk(t, db, chunk)
|
|
}
|
|
dbSize := fileSize(db.Path())
|
|
|
|
for chunk := 0; chunk < chunksAfter; chunk++ {
|
|
insertChunk(t, db, chunksBefore+chunk)
|
|
}
|
|
newDbSize := fileSize(db.Path())
|
|
|
|
if newDbSize <= dbSize {
|
|
t.Errorf("db didn't grow: %v <= %v", newDbSize, dbSize)
|
|
}
|
|
}
|
|
|
|
func insertChunk(t *testing.T, db *btesting.DB, chunkId int) {
|
|
chunkSize := 1024
|
|
|
|
if err := db.Update(func(tx *bolt.Tx) error {
|
|
b, err := tx.CreateBucketIfNotExists([]byte("bucket"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
for i := 0; i < chunkSize; i++ {
|
|
key := []byte(fmt.Sprintf("key-%d-%d", chunkId, i))
|
|
value := []byte("value")
|
|
if err := b.Put(key, value); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
// Main reason for this check is travis limiting mlockable memory to 64KB
|
|
// https://github.com/travis-ci/travis-ci/issues/2462
|
|
func skipOnMemlockLimitBelow(t *testing.T, memlockLimitRequest uint64) {
|
|
var info unix.Rlimit
|
|
if err := unix.Getrlimit(unix.RLIMIT_MEMLOCK, &info); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if info.Cur < memlockLimitRequest {
|
|
t.Skipf(
|
|
"skipping as RLIMIT_MEMLOCK is insufficient: %v < %v",
|
|
info.Cur,
|
|
memlockLimitRequest,
|
|
)
|
|
}
|
|
}
|