ethdb: add basic and parallel sanity tests (#14938)
* ethdb: add basic sanity test * ethdb: test MemDatabase * ethdb: add parallel tests
This commit is contained in:
		
							parent
							
								
									e063d538b8
								
							
						
					
					
						commit
						6f8c7b0def
					
				| @ -14,21 +14,164 @@ | |||||||
| // You should have received a copy of the GNU Lesser General Public License
 | // You should have received a copy of the GNU Lesser General Public License
 | ||||||
| // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
 | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
 | ||||||
| 
 | 
 | ||||||
| package ethdb | package ethdb_test | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
|  | 	"bytes" | ||||||
|  | 	"fmt" | ||||||
|  | 	"io/ioutil" | ||||||
| 	"os" | 	"os" | ||||||
| 	"path/filepath" | 	"strconv" | ||||||
|  | 	"sync" | ||||||
|  | 	"testing" | ||||||
| 
 | 
 | ||||||
| 	"github.com/ethereum/go-ethereum/common" | 	"github.com/ethereum/go-ethereum/ethdb" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func newDb() *LDBDatabase { | func newTestLDB() (*ethdb.LDBDatabase, func()) { | ||||||
| 	file := filepath.Join("/", "tmp", "ldbtesttmpfile") | 	dirname, err := ioutil.TempDir(os.TempDir(), "ethdb_test_") | ||||||
| 	if common.FileExist(file) { | 	if err != nil { | ||||||
| 		os.RemoveAll(file) | 		panic("failed to create test file: " + err.Error()) | ||||||
|  | 	} | ||||||
|  | 	db, err := ethdb.NewLDBDatabase(dirname, 0, 0) | ||||||
|  | 	if err != nil { | ||||||
|  | 		panic("failed to create test database: " + err.Error()) | ||||||
| 	} | 	} | ||||||
| 	db, _ := NewLDBDatabase(file, 0, 0) |  | ||||||
| 
 | 
 | ||||||
| 	return db | 	return db, func() { | ||||||
|  | 		db.Close() | ||||||
|  | 		os.RemoveAll(dirname) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | var test_values = []string{"", "a", "1251", "\x00123\x00"} | ||||||
|  | 
 | ||||||
|  | func TestLDB_PutGet(t *testing.T) { | ||||||
|  | 	db, remove := newTestLDB() | ||||||
|  | 	defer remove() | ||||||
|  | 	testPutGet(db, t) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestMemoryDB_PutGet(t *testing.T) { | ||||||
|  | 	db, _ := ethdb.NewMemDatabase() | ||||||
|  | 	testPutGet(db, t) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func testPutGet(db ethdb.Database, t *testing.T) { | ||||||
|  | 	t.Parallel() | ||||||
|  | 
 | ||||||
|  | 	for _, v := range test_values { | ||||||
|  | 		err := db.Put([]byte(v), []byte(v)) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatalf("put failed: %v", err) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for _, v := range test_values { | ||||||
|  | 		data, err := db.Get([]byte(v)) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatalf("get failed: %v", err) | ||||||
|  | 		} | ||||||
|  | 		if !bytes.Equal(data, []byte(v)) { | ||||||
|  | 			t.Fatalf("get returned wrong result, got %q expected %q", string(data), v) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for _, v := range test_values { | ||||||
|  | 		err := db.Put([]byte(v), []byte("?")) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatalf("put override failed: %v", err) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for _, v := range test_values { | ||||||
|  | 		data, err := db.Get([]byte(v)) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatalf("get failed: %v", err) | ||||||
|  | 		} | ||||||
|  | 		if !bytes.Equal(data, []byte("?")) { | ||||||
|  | 			t.Fatalf("get returned wrong result, got %q expected ?", string(data)) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for _, v := range test_values { | ||||||
|  | 		err := db.Delete([]byte(v)) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatalf("delete %q failed: %v", v, err) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for _, v := range test_values { | ||||||
|  | 		_, err := db.Get([]byte(v)) | ||||||
|  | 		if err == nil { | ||||||
|  | 			t.Fatalf("got deleted value %q", v) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestLDB_ParallelPutGet(t *testing.T) { | ||||||
|  | 	db, remove := newTestLDB() | ||||||
|  | 	defer remove() | ||||||
|  | 	testParallelPutGet(db, t) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestMemoryDB_ParallelPutGet(t *testing.T) { | ||||||
|  | 	db, _ := ethdb.NewMemDatabase() | ||||||
|  | 	testParallelPutGet(db, t) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func testParallelPutGet(db ethdb.Database, t *testing.T) { | ||||||
|  | 	const n = 8 | ||||||
|  | 	var pending sync.WaitGroup | ||||||
|  | 
 | ||||||
|  | 	pending.Add(n) | ||||||
|  | 	for i := 0; i < n; i++ { | ||||||
|  | 		go func(key string) { | ||||||
|  | 			defer pending.Done() | ||||||
|  | 			err := db.Put([]byte(key), []byte("v"+key)) | ||||||
|  | 			if err != nil { | ||||||
|  | 				panic("put failed: " + err.Error()) | ||||||
|  | 			} | ||||||
|  | 		}(strconv.Itoa(i)) | ||||||
|  | 	} | ||||||
|  | 	pending.Wait() | ||||||
|  | 
 | ||||||
|  | 	pending.Add(n) | ||||||
|  | 	for i := 0; i < n; i++ { | ||||||
|  | 		go func(key string) { | ||||||
|  | 			defer pending.Done() | ||||||
|  | 			data, err := db.Get([]byte(key)) | ||||||
|  | 			if err != nil { | ||||||
|  | 				panic("get failed: " + err.Error()) | ||||||
|  | 			} | ||||||
|  | 			if !bytes.Equal(data, []byte("v"+key)) { | ||||||
|  | 				panic(fmt.Sprintf("get failed, got %q expected %q", []byte(data), []byte("v"+key))) | ||||||
|  | 			} | ||||||
|  | 		}(strconv.Itoa(i)) | ||||||
|  | 	} | ||||||
|  | 	pending.Wait() | ||||||
|  | 
 | ||||||
|  | 	pending.Add(n) | ||||||
|  | 	for i := 0; i < n; i++ { | ||||||
|  | 		go func(key string) { | ||||||
|  | 			defer pending.Done() | ||||||
|  | 			err := db.Delete([]byte(key)) | ||||||
|  | 			if err != nil { | ||||||
|  | 				panic("delete failed: " + err.Error()) | ||||||
|  | 			} | ||||||
|  | 		}(strconv.Itoa(i)) | ||||||
|  | 	} | ||||||
|  | 	pending.Wait() | ||||||
|  | 
 | ||||||
|  | 	pending.Add(n) | ||||||
|  | 	for i := 0; i < n; i++ { | ||||||
|  | 		go func(key string) { | ||||||
|  | 			defer pending.Done() | ||||||
|  | 			_, err := db.Get([]byte(key)) | ||||||
|  | 			if err == nil { | ||||||
|  | 				panic("get succeeded") | ||||||
|  | 			} | ||||||
|  | 		}(strconv.Itoa(i)) | ||||||
|  | 	} | ||||||
|  | 	pending.Wait() | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user