mirror of https://github.com/etcd-io/bbolt.git
simulation_test.go: fix swallowed goroutine error statements
simulation_test.go: add loggingpull/176/head
parent
14ae4453e2
commit
0e02572955
|
@ -5,6 +5,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"sync"
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
bolt "go.etcd.io/bbolt"
|
bolt "go.etcd.io/bbolt"
|
||||||
|
@ -47,15 +48,28 @@ func testSimulate(t *testing.T, openOption *bolt.Options, round, threadCount, pa
|
||||||
|
|
||||||
var mutex sync.Mutex
|
var mutex sync.Mutex
|
||||||
|
|
||||||
// Run n threads in parallel, each with their own operation.
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
|
|
||||||
for n := 0; n < round; n++ {
|
for n := 0; n < round; n++ {
|
||||||
|
// Run n threads in parallel, each with their own operation.
|
||||||
var threads = make(chan bool, parallelism)
|
var threads = make(chan bool, parallelism)
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
|
// counter for how many goroutines were fired
|
||||||
|
var opCount int64
|
||||||
|
|
||||||
|
// counter for ignored operations
|
||||||
|
var igCount int64
|
||||||
|
|
||||||
|
var errCh = make(chan error, threadCount)
|
||||||
|
|
||||||
var i int
|
var i int
|
||||||
for {
|
for {
|
||||||
|
// this buffered channel will keep accepting booleans
|
||||||
|
// until it hits the limit defined by the parallelism
|
||||||
|
// argument to testSimulate()
|
||||||
threads <- true
|
threads <- true
|
||||||
|
|
||||||
|
// this wait group can only be marked "done" from inside
|
||||||
|
// the subsequent goroutine
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
writable := ((rand.Int() % 100) < 20) // 20% writers
|
writable := ((rand.Int() % 100) < 20) // 20% writers
|
||||||
|
|
||||||
|
@ -70,11 +84,12 @@ func testSimulate(t *testing.T, openOption *bolt.Options, round, threadCount, pa
|
||||||
// Execute a thread for the given operation.
|
// Execute a thread for the given operation.
|
||||||
go func(writable bool, handler simulateHandler) {
|
go func(writable bool, handler simulateHandler) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
|
atomic.AddInt64(&opCount, 1)
|
||||||
// Start transaction.
|
// Start transaction.
|
||||||
tx, err := db.Begin(writable)
|
tx, err := db.Begin(writable)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("tx begin: ", err)
|
errCh <- fmt.Errorf("error tx begin: %v", err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtain current state of the dataset.
|
// Obtain current state of the dataset.
|
||||||
|
@ -93,7 +108,8 @@ func testSimulate(t *testing.T, openOption *bolt.Options, round, threadCount, pa
|
||||||
mutex.Unlock()
|
mutex.Unlock()
|
||||||
|
|
||||||
if err := tx.Commit(); err != nil {
|
if err := tx.Commit(); err != nil {
|
||||||
t.Fatal(err)
|
errCh <- err
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
} else {
|
} else {
|
||||||
|
@ -102,6 +118,7 @@ func testSimulate(t *testing.T, openOption *bolt.Options, round, threadCount, pa
|
||||||
|
|
||||||
// Ignore operation if we don't have data yet.
|
// Ignore operation if we don't have data yet.
|
||||||
if qdb == nil {
|
if qdb == nil {
|
||||||
|
atomic.AddInt64(&igCount, 1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,17 +130,25 @@ func testSimulate(t *testing.T, openOption *bolt.Options, round, threadCount, pa
|
||||||
}(writable, handler)
|
}(writable, handler)
|
||||||
|
|
||||||
i++
|
i++
|
||||||
if i > threadCount {
|
if i >= threadCount {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait until all threads are done.
|
// Wait until all threads are done.
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
t.Logf("transactions:%d ignored:%d", opCount, igCount)
|
||||||
|
close(errCh)
|
||||||
|
for err := range errCh {
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error from inside goroutine: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
db.MustClose()
|
db.MustClose()
|
||||||
db.MustReopen()
|
db.MustReopen()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type simulateHandler func(tx *bolt.Tx, qdb *QuickDB)
|
type simulateHandler func(tx *bolt.Tx, qdb *QuickDB)
|
||||||
|
|
Loading…
Reference in New Issue