Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tests: Do not leave behind state goroutines #1349

Merged
merged 17 commits into from
Jun 9, 2020
10 changes: 9 additions & 1 deletion db.go
Original file line number Diff line number Diff line change
@@ -378,7 +378,15 @@ func Open(opt Options) (db *DB, err error) {
go db.doWrites(replayCloser)

if err = db.vlog.open(db, vptr, db.replayFunction()); err != nil {
return db, y.Wrapf(err, "During db.vlog.open")
// Perform cleanup.
replayCloser.SignalAndWait()
db.closers.updateSize.SignalAndWait()
db.blockCache.Close()
db.bfCache.Close()
db.orc.Stop()
db.vlog.Close()

return nil, y.Wrapf(err, "During db.vlog.open")
}
replayCloser.SignalAndWait() // Wait for replay to be applied first.

20 changes: 12 additions & 8 deletions db_test.go
Original file line number Diff line number Diff line change
@@ -1265,8 +1265,11 @@ func TestExpiry(t *testing.T) {
func TestExpiryImproperDBClose(t *testing.T) {
testReplay := func(opt Options) {

db0, err := Open(opt)
// L0 compaction doesn't affect the test in any way. It is set to allow
// graceful shutdown of db0.
db0, err := Open(opt.WithCompactL0OnClose(false))
require.NoError(t, err)
defer func() { require.NoError(t, db0.Close()) }()

dur := 1 * time.Hour
expiryTime := uint64(time.Now().Add(dur).Unix())
@@ -1280,18 +1283,19 @@ func TestExpiryImproperDBClose(t *testing.T) {
// Simulate a crash by not closing db0, but releasing the locks.
if db0.dirLockGuard != nil {
require.NoError(t, db0.dirLockGuard.release())
db0.dirLockGuard = nil
}
if db0.valueDirGuard != nil {
require.NoError(t, db0.valueDirGuard.release())
db0.valueDirGuard = nil
}
// We need to close vlog to fix the vlog file size. On windows, the vlog file
// is truncated to 2*MaxVlogSize and if we don't close the vlog file, reopening
// it would return Truncate Required Error.
require.NoError(t, db0.vlog.Close())

require.NoError(t, db0.registry.Close())
require.NoError(t, db0.manifest.close())

// On windows, the vlog file is truncated to 2*MaxVlogSize and if we
// do not set the trucate flag, reopening the db would return Truncate
// Required Error.
if runtime.GOOS == "windows" {
opt.Truncate = true
}
db1, err := Open(opt)
require.NoError(t, err)
err = db1.View(func(txn *Txn) error {
9 changes: 9 additions & 0 deletions levels_test.go
Original file line number Diff line number Diff line change
@@ -538,6 +538,15 @@ func TestL0Stall(t *testing.T) {
t.Log("Timeout triggered")
// Mark this test as successful since L0 is in memory and the
// addition of new table to L0 is supposed to stall.

// Remove tables from level 0 so that the stalled
// compaction can make progress. This does not have any
// effect on the test. This is done so that the goroutine
// stuck on addLevel0Table can make progress and end.
db.lc.levels[0].Lock()
db.lc.levels[0].tables = nil
db.lc.levels[0].Unlock()
<-done
} else {
t.Fatal("Test didn't finish in time")
}
6 changes: 4 additions & 2 deletions managed_db_test.go
Original file line number Diff line number Diff line change
@@ -162,6 +162,7 @@ func TestDropAllTwice(t *testing.T) {

// Call DropAll again.
require.NoError(t, db.DropAll())
require.NoError(t, db.Close())
}
t.Run("disk mode", func(t *testing.T) {
dir, err := ioutil.TempDir("", "badger-test")
@@ -175,7 +176,6 @@ func TestDropAllTwice(t *testing.T) {
opts := getTestOptions("")
opts.InMemory = true
test(t, opts)

})
}

@@ -280,6 +280,7 @@ func TestDropReadOnly(t *testing.T) {
require.NoError(t, err)
}
require.Panics(t, func() { db2.DropAll() })
require.NoError(t, db2.Close())
}

func TestWriteAfterClose(t *testing.T) {
@@ -525,6 +526,7 @@ func TestDropPrefixReadOnly(t *testing.T) {
require.NoError(t, err)
}
require.Panics(t, func() { db2.DropPrefix([]byte("key0")) })
require.NoError(t, db2.Close())
}

func TestDropPrefixRace(t *testing.T) {
@@ -590,7 +592,7 @@ func TestDropPrefixRace(t *testing.T) {
after := numKeysManaged(db, math.MaxUint64)
t.Logf("Before: %d. After dropprefix: %d\n", before, after)
require.True(t, after < before)
db.Close()
require.NoError(t, db.Close())
}

func TestWriteBatchManagedMode(t *testing.T) {
1 change: 1 addition & 0 deletions stream_writer.go
Original file line number Diff line number Diff line change
@@ -229,6 +229,7 @@ func (sw *StreamWriter) Flush() error {
if err := headWriter.Done(); err != nil {
return err
}
headWriter.closer.SignalAndWait()

if !sw.db.opt.managedTxns {
if sw.db.orc != nil {
6 changes: 3 additions & 3 deletions value_test.go
Original file line number Diff line number Diff line change
@@ -762,6 +762,7 @@ func TestPenultimateLogCorruption(t *testing.T) {

db0, err := Open(opt)
require.NoError(t, err)
defer func() { require.NoError(t, db0.Close()) }()

h := testHelper{db: db0, t: t}
h.writeRange(0, 7)
@@ -780,13 +781,12 @@ func TestPenultimateLogCorruption(t *testing.T) {
// Simulate a crash by not closing db0, but releasing the locks.
if db0.dirLockGuard != nil {
require.NoError(t, db0.dirLockGuard.release())
db0.dirLockGuard = nil
}
if db0.valueDirGuard != nil {
require.NoError(t, db0.valueDirGuard.release())
db0.valueDirGuard = nil
}
require.NoError(t, db0.vlog.Close())
require.NoError(t, db0.manifest.close())
require.NoError(t, db0.registry.Close())

opt.Truncate = true
db1, err := Open(opt)