make mmap test experiment with different amounts of mapping

This is sort of prototype-ish, but the idea is that we use SetMaxMapCount
from syswrap, which already exists, to let us test edge cases like
"what happens if you only sometimes have mapped data".
This commit is contained in:
Seebs 2020-02-05 15:02:11 -06:00 committed by Matt Jaffee
parent 63fb2f8539
commit cb686dcad0
No known key found for this signature in database
GPG key ID: 08A3DFFF987B11BF
4 changed files with 40 additions and 10 deletions

View file

@ -15,11 +15,13 @@
package pilosa
import (
"fmt"
"math/rand"
"runtime"
"testing"
"github.com/pilosa/pilosa/v2/logger"
"github.com/pilosa/pilosa/v2/syswrap"
)
type cv struct {
@ -27,11 +29,7 @@ type cv struct {
vals []int64
}
// This test should basically never fail, but it might if you were running
// out of available mmaps. Which you can fake up by adding '&& false' to the test
// in newGeneration in generation.go. So this is probably useless but it's
// a failure mode we've been bitten by once...
func TestMmapBehavior(t *testing.T) {
func forceSnapshotsCheckMapping(t *testing.T) {
depth := uint(6)
f := mustOpenBSIFragment("i", "f", viewStandard, 0)
f.Logger = logger.NewLogfLogger(t)
@ -64,7 +62,11 @@ func TestMmapBehavior(t *testing.T) {
// then invalidates the other map...
for i := 0; i < 32; i++ {
cv := values[i%len(values)]
runtime.GC()
// periodically force gc, so if we have a small pool of maps
// we'll go in and out of mapping mode
if i%5 == 0 {
runtime.GC()
}
err := f.importValue(cv.cols, cv.vals, depth, (i%3 == 1))
if err != nil {
t.Fatalf("importValue[%d]: %v", i, err)
@ -75,3 +77,26 @@ func TestMmapBehavior(t *testing.T) {
}
}
}
// This test should basically never fail, but it might if you were running
// out of available mmaps. Which you can fake up by adding '&& false' to the test
// in newGeneration in generation.go. So this is probably useless but it's
// a failure mode we've been bitten by once...
func TestMmapBehavior(t *testing.T) {
var changed bool
var original uint64
defer func() {
syswrap.SetMaxMapCount(original)
}()
for _, mmapMaxVal := range []uint64{0, 3} {
prev := syswrap.SetMaxMapCount(mmapMaxVal)
if !changed {
original = prev
changed = true
}
t.Run(fmt.Sprintf("maps%d", mmapMaxVal), func(t *testing.T) {
forceSnapshotsCheckMapping(t)
})
}
}

View file

@ -229,8 +229,8 @@ func (m *Command) SetupServer() error {
runtime.SetBlockProfileRate(m.Config.Profile.BlockRate)
runtime.SetMutexProfileFraction(m.Config.Profile.MutexFraction)
syswrap.SetMaxMapCount(m.Config.MaxMapCount)
syswrap.SetMaxFileCount(m.Config.MaxFileCount)
_ = syswrap.SetMaxMapCount(m.Config.MaxMapCount)
_ = syswrap.SetMaxFileCount(m.Config.MaxFileCount)
err := m.setupLogger()
if err != nil {

View file

@ -34,10 +34,13 @@ var ErrMaxMapCountReached = errors.New("maximum map count reached")
var maxMapCount uint64 = 60000
var mu sync.RWMutex
func SetMaxMapCount(max uint64) {
// SetMaxMapCount sets the maximum map count, and returns the previous maximum.
func SetMaxMapCount(max uint64) uint64 {
prev := maxMapCount
mu.Lock()
maxMapCount = max
mu.Unlock()
return prev
}
// Mmap increments the global map count, and then calls syscall.Mmap. It

View file

@ -27,10 +27,12 @@ var fileCount uint64
var maxFileCount uint64 = 500000
var fileMu sync.RWMutex
func SetMaxFileCount(max uint64) {
func SetMaxFileCount(max uint64) uint64 {
prev := maxFileCount
fileMu.Lock()
maxFileCount = max
fileMu.Unlock()
return prev
}
// OpenFile passes the arguments along to os.OpenFile while incrementing a