...

Source file src/go.etcd.io/bbolt/unix_test.go

Documentation: go.etcd.io/bbolt

     1  //go:build !windows
     2  // +build !windows
     3  
     4  package bbolt_test
     5  
     6  import (
     7  	"fmt"
     8  	"testing"
     9  
    10  	"golang.org/x/sys/unix"
    11  
    12  	bolt "go.etcd.io/bbolt"
    13  	"go.etcd.io/bbolt/internal/btesting"
    14  )
    15  
    16  func TestMlock_DbOpen(t *testing.T) {
    17  	// 32KB
    18  	skipOnMemlockLimitBelow(t, 32*1024)
    19  
    20  	btesting.MustCreateDBWithOption(t, &bolt.Options{Mlock: true})
    21  }
    22  
    23  // Test change between "empty" (16KB) and "non-empty" db
    24  func TestMlock_DbCanGrow_Small(t *testing.T) {
    25  	// 32KB
    26  	skipOnMemlockLimitBelow(t, 32*1024)
    27  
    28  	db := btesting.MustCreateDBWithOption(t, &bolt.Options{Mlock: true})
    29  
    30  	if err := db.Update(func(tx *bolt.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 := btesting.MustCreateDBWithOption(t, &bolt.Options{Mlock: true})
    62  
    63  	for chunk := 0; chunk < chunksBefore; chunk++ {
    64  		insertChunk(t, db, chunk)
    65  	}
    66  	dbSize := fileSize(db.Path())
    67  
    68  	for chunk := 0; chunk < chunksAfter; chunk++ {
    69  		insertChunk(t, db, chunksBefore+chunk)
    70  	}
    71  	newDbSize := fileSize(db.Path())
    72  
    73  	if newDbSize <= dbSize {
    74  		t.Errorf("db didn't grow: %v <= %v", newDbSize, dbSize)
    75  	}
    76  }
    77  
    78  func insertChunk(t *testing.T, db *btesting.DB, chunkId int) {
    79  	chunkSize := 1024
    80  
    81  	if err := db.Update(func(tx *bolt.Tx) error {
    82  		b, err := tx.CreateBucketIfNotExists([]byte("bucket"))
    83  		if err != nil {
    84  			t.Fatal(err)
    85  		}
    86  
    87  		for i := 0; i < chunkSize; i++ {
    88  			key := []byte(fmt.Sprintf("key-%d-%d", chunkId, i))
    89  			value := []byte("value")
    90  			if err := b.Put(key, value); err != nil {
    91  				t.Fatal(err)
    92  			}
    93  		}
    94  
    95  		return nil
    96  	}); err != nil {
    97  		t.Fatal(err)
    98  	}
    99  }
   100  
   101  // Main reason for this check is travis limiting mlockable memory to 64KB
   102  // https://github.com/travis-ci/travis-ci/issues/2462
   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.Skipf(
   111  			"skipping as RLIMIT_MEMLOCK is insufficient: %v < %v",
   112  			info.Cur,
   113  			memlockLimitRequest,
   114  		)
   115  	}
   116  }
   117  

View as plain text