Skip to content

Commit

Permalink
Merge pull request #546 from vianamjr/failpoint-lack-of-disk-space
Browse files Browse the repository at this point in the history
tests: add failpoint to simulate lack of disk space
  • Loading branch information
ahrtr authored Jul 31, 2023
2 parents d0a911e + 5ddbd0c commit 808aac7
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 6 deletions.
33 changes: 33 additions & 0 deletions tests/failpoint/db_failpoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/stretchr/testify/require"

bolt "go.etcd.io/bbolt"
"go.etcd.io/bbolt/errors"
"go.etcd.io/bbolt/internal/btesting"
gofail "go.etcd.io/gofail/runtime"
)
Expand Down Expand Up @@ -122,3 +123,35 @@ func TestFailpoint_ResizeFileFail(t *testing.T) {

require.NoError(t, err)
}

func TestFailpoint_LackOfDiskSpace(t *testing.T) {
db := btesting.MustCreateDB(t)

err := gofail.Enable("lackOfDiskSpace", `return("grow somehow failed")`)
require.NoError(t, err)

tx, err := db.Begin(true)
require.NoError(t, err)

err = tx.Commit()
require.Error(t, err)
require.ErrorContains(t, err, "grow somehow failed")

err = tx.Rollback()
require.Error(t, err)
require.ErrorIs(t, err, errors.ErrTxClosed)

// It should work after disabling the failpoint.
err = gofail.Disable("lackOfDiskSpace")
require.NoError(t, err)

tx, err = db.Begin(true)
require.NoError(t, err)

err = tx.Commit()
require.NoError(t, err)

err = tx.Rollback()
require.Error(t, err)
require.ErrorIs(t, err, errors.ErrTxClosed)
}
17 changes: 11 additions & 6 deletions tx.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package bbolt

import (
"errors"
"fmt"
"io"
"os"
Expand All @@ -10,7 +11,7 @@ import (
"time"
"unsafe"

"go.etcd.io/bbolt/errors"
berrors "go.etcd.io/bbolt/errors"
"go.etcd.io/bbolt/internal/common"
)

Expand Down Expand Up @@ -142,9 +143,9 @@ func (tx *Tx) OnCommit(fn func()) {
func (tx *Tx) Commit() error {
common.Assert(!tx.managed, "managed tx commit not allowed")
if tx.db == nil {
return errors.ErrTxClosed
return berrors.ErrTxClosed
} else if !tx.writable {
return errors.ErrTxNotWritable
return berrors.ErrTxNotWritable
}

// TODO(benbjohnson): Use vectorized I/O to write out dirty pages.
Expand Down Expand Up @@ -185,6 +186,10 @@ func (tx *Tx) Commit() error {

// If the high water mark has moved up then attempt to grow the database.
if tx.meta.Pgid() > opgid {
_ = errors.New("")
// gofail: var lackOfDiskSpace string
// tx.rollback()
// return errors.New(lackOfDiskSpace)
if err := tx.db.grow(int(tx.meta.Pgid()+1) * tx.db.pageSize); err != nil {
tx.rollback()
return err
Expand Down Expand Up @@ -254,7 +259,7 @@ func (tx *Tx) commitFreelist() error {
func (tx *Tx) Rollback() error {
common.Assert(!tx.managed, "managed tx rollback not allowed")
if tx.db == nil {
return errors.ErrTxClosed
return berrors.ErrTxClosed
}
tx.nonPhysicalRollback()
return nil
Expand Down Expand Up @@ -561,13 +566,13 @@ func (tx *Tx) forEachPageInternal(pgidstack []common.Pgid, fn func(*common.Page,
// This is only safe for concurrent use when used by a writable transaction.
func (tx *Tx) Page(id int) (*common.PageInfo, error) {
if tx.db == nil {
return nil, errors.ErrTxClosed
return nil, berrors.ErrTxClosed
} else if common.Pgid(id) >= tx.meta.Pgid() {
return nil, nil
}

if tx.db.freelist == nil {
return nil, errors.ErrFreePagesNotLoaded
return nil, berrors.ErrFreePagesNotLoaded
}

// Build the page info.
Expand Down

0 comments on commit 808aac7

Please sign in to comment.