testutil: add 'with generated key/value' to AllKeyValueTesting; and implements BeforeSuite, AfterSuite setup and teardown
diff --git a/leveldb/external_test.go b/leveldb/external_test.go
index afbf594..1ae304e 100644
--- a/leveldb/external_test.go
+++ b/leveldb/external_test.go
@@ -19,7 +19,7 @@
 		o := &opt.Options{
 			BlockCache:           opt.NoCache,
 			BlockRestartInterval: 5,
-			BlockSize:            50,
+			BlockSize:            80,
 			Compression:          opt.NoCompression,
 			CachedOpenFiles:      -1,
 			Strict:               opt.StrictAll,
diff --git a/leveldb/iterator/iter_suite_test.go b/leveldb/iterator/iter_suite_test.go
index 7ec2fc6..5ef8d5b 100644
--- a/leveldb/iterator/iter_suite_test.go
+++ b/leveldb/iterator/iter_suite_test.go
@@ -3,15 +3,9 @@
 import (
 	"testing"
 
-	. "github.com/onsi/ginkgo"
-	. "github.com/onsi/gomega"
-
 	"github.com/syndtr/goleveldb/leveldb/testutil"
 )
 
 func TestIterator(t *testing.T) {
-	testutil.RunDefer()
-
-	RegisterFailHandler(Fail)
-	RunSpecs(t, "Iterator Suite")
+	testutil.RunSuite(t, "Iterator Suite")
 }
diff --git a/leveldb/leveldb_suite_test.go b/leveldb/leveldb_suite_test.go
index 245b1fd..fefa007 100644
--- a/leveldb/leveldb_suite_test.go
+++ b/leveldb/leveldb_suite_test.go
@@ -3,18 +3,9 @@
 import (
 	"testing"
 
-	. "github.com/onsi/ginkgo"
-	. "github.com/onsi/gomega"
-
 	"github.com/syndtr/goleveldb/leveldb/testutil"
 )
 
-func TestLeveldb(t *testing.T) {
-	testutil.RunDefer()
-
-	RegisterFailHandler(Fail)
-	RunSpecs(t, "Leveldb Suite")
-
-	RegisterTestingT(t)
-	testutil.RunDefer("teardown")
+func TestLevelDB(t *testing.T) {
+	testutil.RunSuite(t, "LevelDB Suite")
 }
diff --git a/leveldb/memdb/memdb_suite_test.go b/leveldb/memdb/memdb_suite_test.go
index 788539a..18c304b 100644
--- a/leveldb/memdb/memdb_suite_test.go
+++ b/leveldb/memdb/memdb_suite_test.go
@@ -3,15 +3,9 @@
 import (
 	"testing"
 
-	. "github.com/onsi/ginkgo"
-	. "github.com/onsi/gomega"
-
 	"github.com/syndtr/goleveldb/leveldb/testutil"
 )
 
-func TestMemdb(t *testing.T) {
-	testutil.RunDefer()
-
-	RegisterFailHandler(Fail)
-	RunSpecs(t, "Memdb Suite")
+func TestMemDB(t *testing.T) {
+	testutil.RunSuite(t, "MemDB Suite")
 }
diff --git a/leveldb/table/table_suite_test.go b/leveldb/table/table_suite_test.go
index bc9eb83..6465da6 100644
--- a/leveldb/table/table_suite_test.go
+++ b/leveldb/table/table_suite_test.go
@@ -3,15 +3,9 @@
 import (
 	"testing"
 
-	. "github.com/onsi/ginkgo"
-	. "github.com/onsi/gomega"
-
 	"github.com/syndtr/goleveldb/leveldb/testutil"
 )
 
 func TestTable(t *testing.T) {
-	testutil.RunDefer()
-
-	RegisterFailHandler(Fail)
-	RunSpecs(t, "Table Suite")
+	testutil.RunSuite(t, "Table Suite")
 }
diff --git a/leveldb/testutil/ginkgo.go b/leveldb/testutil/ginkgo.go
new file mode 100644
index 0000000..82f3d0e
--- /dev/null
+++ b/leveldb/testutil/ginkgo.go
@@ -0,0 +1,21 @@
+package testutil
+
+import (
+	. "github.com/onsi/ginkgo"
+	. "github.com/onsi/gomega"
+)
+
+func RunSuite(t GinkgoTestingT, name string) {
+	RunDefer()
+
+	SynchronizedBeforeSuite(func() []byte {
+		RunDefer("setup")
+		return nil
+	}, func(data []byte) {})
+	SynchronizedAfterSuite(func() {
+		RunDefer("teardown")
+	}, func() {})
+
+	RegisterFailHandler(Fail)
+	RunSpecs(t, name)
+}
diff --git a/leveldb/testutil/kvtest.go b/leveldb/testutil/kvtest.go
index d7c7715..a0b58f0 100644
--- a/leveldb/testutil/kvtest.go
+++ b/leveldb/testutil/kvtest.go
@@ -26,9 +26,11 @@
 		BeforeEach(func() {
 			p = setup(kv)
 		})
-		AfterEach(func() {
-			teardown(p)
-		})
+		if teardown != nil {
+			AfterEach(func() {
+				teardown(p)
+			})
+		}
 	}
 
 	It("Should find all keys with Find", func() {
@@ -124,7 +126,7 @@
 		done <- true
 	}, 3.0)
 
-	RandomIndex(rnd, kv.Len(), kv.Len(), func(i int) {
+	RandomIndex(rnd, kv.Len(), Min(kv.Len(), 50), func(i int) {
 		type slice struct {
 			r            *util.Range
 			start, limit int
@@ -142,7 +144,7 @@
 		}
 	})
 
-	RandomRange(rnd, kv.Len(), kv.Len(), func(start, limit int) {
+	RandomRange(rnd, kv.Len(), Min(kv.Len(), 50), func(start, limit int) {
 		It(fmt.Sprintf("Should iterates and seeks correctly of a slice %d .. %d", start, limit), func(done Done) {
 			r := kv.Range(start, limit)
 			TestIter(&r, kv.Slice(start, limit))
@@ -155,10 +157,22 @@
 	Test := func(kv *KeyValue) func() {
 		return func() {
 			var p DB
+			if setup != nil {
+				Defer("setup", func() {
+					p = setup(*kv)
+				})
+			}
+			if teardown != nil {
+				Defer("teardown", func() {
+					teardown(p)
+				})
+			}
 			if body != nil {
 				p = body(*kv)
 			}
-			KeyValueTesting(rnd, *kv, p, setup, teardown)
+			KeyValueTesting(rnd, *kv, p, func(KeyValue) DB {
+				return p
+			}, nil)
 		}
 	}
 
@@ -169,4 +183,5 @@
 	Describe("with big value", Test(KeyValue_BigValue()))
 	Describe("with special key", Test(KeyValue_SpecialKey()))
 	Describe("with multiple key/value", Test(KeyValue_MultipleKeyValue()))
+	Describe("with generated key/value", Test(KeyValue_Generate(nil, 120, 1, 50, 10, 120)))
 }
diff --git a/leveldb/testutil/storage.go b/leveldb/testutil/storage.go
index 0f8d77a..59c496d 100644
--- a/leveldb/testutil/storage.go
+++ b/leveldb/testutil/storage.go
@@ -397,6 +397,7 @@
 
 func (s *Storage) Log(str string) {
 	s.log(1, "Log: "+str)
+	s.Storage.Log(str)
 }
 
 func (s *Storage) Lock() (r util.Releaser, err error) {
diff --git a/leveldb/testutil/util.go b/leveldb/testutil/util.go
index 38fe25d..97c5294 100644
--- a/leveldb/testutil/util.go
+++ b/leveldb/testutil/util.go
@@ -155,3 +155,17 @@
 	}
 	return
 }
+
+func Max(x, y int) int {
+	if x > y {
+		return x
+	}
+	return y
+}
+
+func Min(x, y int) int {
+	if x < y {
+		return x
+	}
+	return y
+}