github.com/bhojpur/cache@v0.0.4/pkg/memory/unix_test.go (about)

     1  //go:build !windows
     2  // +build !windows
     3  
     4  package memory_test
     5  
     6  import (
     7  	"fmt"
     8  	"testing"
     9  
    10  	memcache "github.com/bhojpur/cache/pkg/memory"
    11  	"golang.org/x/sys/unix"
    12  )
    13  
    14  func TestMlock_DbOpen(t *testing.T) {
    15  	// 32KB
    16  	skipOnMemlockLimitBelow(t, 32*1024)
    17  
    18  	db := MustOpenWithOption(&memcache.Options{Mlock: true})
    19  	defer db.MustClose()
    20  }
    21  
    22  // Test change between "empty" (16KB) and "non-empty" db
    23  func TestMlock_DbCanGrow_Small(t *testing.T) {
    24  	// 32KB
    25  	skipOnMemlockLimitBelow(t, 32*1024)
    26  
    27  	db := MustOpenWithOption(&memcache.Options{Mlock: true})
    28  	defer db.MustClose()
    29  
    30  	if err := db.Update(func(tx *memcache.Tx) error {
    31  		b, err := tx.CreateBucketIfNotExists([]byte("bucket"))
    32  		if err != nil {
    33  			t.Fatal(err)
    34  		}
    35  
    36  		key := []byte("key")
    37  		value := []byte("value")
    38  		if err := b.Put(key, value); err != nil {
    39  			t.Fatal(err)
    40  		}
    41  
    42  		return nil
    43  	}); err != nil {
    44  		t.Fatal(err)
    45  	}
    46  
    47  }
    48  
    49  // Test crossing of 16MB (AllocSize) of db size
    50  func TestMlock_DbCanGrow_Big(t *testing.T) {
    51  	if testing.Short() {
    52  		t.Skip("skipping test in short mode")
    53  	}
    54  
    55  	// 32MB
    56  	skipOnMemlockLimitBelow(t, 32*1024*1024)
    57  
    58  	chunksBefore := 64
    59  	chunksAfter := 64
    60  
    61  	db := MustOpenWithOption(&memcache.Options{Mlock: true})
    62  	defer db.MustClose()
    63  
    64  	for chunk := 0; chunk < chunksBefore; chunk++ {
    65  		insertChunk(t, db, chunk)
    66  	}
    67  	dbSize := fileSize(db.f)
    68  
    69  	for chunk := 0; chunk < chunksAfter; chunk++ {
    70  		insertChunk(t, db, chunksBefore+chunk)
    71  	}
    72  	newDbSize := fileSize(db.f)
    73  
    74  	if newDbSize <= dbSize {
    75  		t.Errorf("db didn't grow: %v <= %v", newDbSize, dbSize)
    76  	}
    77  }
    78  
    79  func insertChunk(t *testing.T, db *DB, chunkId int) {
    80  	chunkSize := 1024
    81  
    82  	if err := db.Update(func(tx *memcache.Tx) error {
    83  		b, err := tx.CreateBucketIfNotExists([]byte("bucket"))
    84  		if err != nil {
    85  			t.Fatal(err)
    86  		}
    87  
    88  		for i := 0; i < chunkSize; i++ {
    89  			key := []byte(fmt.Sprintf("key-%d-%d", chunkId, i))
    90  			value := []byte("value")
    91  			if err := b.Put(key, value); err != nil {
    92  				t.Fatal(err)
    93  			}
    94  		}
    95  
    96  		return nil
    97  	}); err != nil {
    98  		t.Fatal(err)
    99  	}
   100  }
   101  
   102  // Main reason for this check is travis limiting mlockable memory to 64KB
   103  func skipOnMemlockLimitBelow(t *testing.T, memlockLimitRequest uint64) {
   104  	var info unix.Rlimit
   105  	if err := unix.Getrlimit(unix.RLIMIT_MEMLOCK, &info); err != nil {
   106  		t.Fatal(err)
   107  	}
   108  
   109  	if info.Cur < memlockLimitRequest {
   110  		t.Skip(fmt.Sprintf(
   111  			"skipping as RLIMIT_MEMLOCK is unsufficient: %v < %v",
   112  			info.Cur,
   113  			memlockLimitRequest,
   114  		))
   115  	}
   116  }