github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/ethdb/database_test.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 19:16:38</date>
    10  //</624450090446098432>
    11  
    12  
    13  //+建设!JS
    14  
    15  package ethdb_test
    16  
    17  import (
    18  	"bytes"
    19  	"fmt"
    20  	"io/ioutil"
    21  	"os"
    22  	"strconv"
    23  	"sync"
    24  	"testing"
    25  
    26  	"github.com/ethereum/go-ethereum/ethdb"
    27  )
    28  
    29  func newTestLDB() (*ethdb.LDBDatabase, func()) {
    30  	dirname, err := ioutil.TempDir(os.TempDir(), "ethdb_test_")
    31  	if err != nil {
    32  		panic("failed to create test file: " + err.Error())
    33  	}
    34  	db, err := ethdb.NewLDBDatabase(dirname, 0, 0)
    35  	if err != nil {
    36  		panic("failed to create test database: " + err.Error())
    37  	}
    38  
    39  	return db, func() {
    40  		db.Close()
    41  		os.RemoveAll(dirname)
    42  	}
    43  }
    44  
    45  var test_values = []string{"", "a", "1251", "\x00123\x00"}
    46  
    47  func TestLDB_PutGet(t *testing.T) {
    48  	db, remove := newTestLDB()
    49  	defer remove()
    50  	testPutGet(db, t)
    51  }
    52  
    53  func TestMemoryDB_PutGet(t *testing.T) {
    54  	testPutGet(ethdb.NewMemDatabase(), t)
    55  }
    56  
    57  func testPutGet(db ethdb.Database, t *testing.T) {
    58  	t.Parallel()
    59  
    60  	for _, k := range test_values {
    61  		err := db.Put([]byte(k), nil)
    62  		if err != nil {
    63  			t.Fatalf("put failed: %v", err)
    64  		}
    65  	}
    66  
    67  	for _, k := range test_values {
    68  		data, err := db.Get([]byte(k))
    69  		if err != nil {
    70  			t.Fatalf("get failed: %v", err)
    71  		}
    72  		if len(data) != 0 {
    73  			t.Fatalf("get returned wrong result, got %q expected nil", string(data))
    74  		}
    75  	}
    76  
    77  	_, err := db.Get([]byte("non-exist-key"))
    78  	if err == nil {
    79  		t.Fatalf("expect to return a not found error")
    80  	}
    81  
    82  	for _, v := range test_values {
    83  		err := db.Put([]byte(v), []byte(v))
    84  		if err != nil {
    85  			t.Fatalf("put failed: %v", err)
    86  		}
    87  	}
    88  
    89  	for _, v := range test_values {
    90  		data, err := db.Get([]byte(v))
    91  		if err != nil {
    92  			t.Fatalf("get failed: %v", err)
    93  		}
    94  		if !bytes.Equal(data, []byte(v)) {
    95  			t.Fatalf("get returned wrong result, got %q expected %q", string(data), v)
    96  		}
    97  	}
    98  
    99  	for _, v := range test_values {
   100  		err := db.Put([]byte(v), []byte("?"))
   101  		if err != nil {
   102  			t.Fatalf("put override failed: %v", err)
   103  		}
   104  	}
   105  
   106  	for _, v := range test_values {
   107  		data, err := db.Get([]byte(v))
   108  		if err != nil {
   109  			t.Fatalf("get failed: %v", err)
   110  		}
   111  		if !bytes.Equal(data, []byte("?")) {
   112  			t.Fatalf("get returned wrong result, got %q expected ?", string(data))
   113  		}
   114  	}
   115  
   116  	for _, v := range test_values {
   117  		orig, err := db.Get([]byte(v))
   118  		if err != nil {
   119  			t.Fatalf("get failed: %v", err)
   120  		}
   121  		orig[0] = byte(0xff)
   122  		data, err := db.Get([]byte(v))
   123  		if err != nil {
   124  			t.Fatalf("get failed: %v", err)
   125  		}
   126  		if !bytes.Equal(data, []byte("?")) {
   127  			t.Fatalf("get returned wrong result, got %q expected ?", string(data))
   128  		}
   129  	}
   130  
   131  	for _, v := range test_values {
   132  		err := db.Delete([]byte(v))
   133  		if err != nil {
   134  			t.Fatalf("delete %q failed: %v", v, err)
   135  		}
   136  	}
   137  
   138  	for _, v := range test_values {
   139  		_, err := db.Get([]byte(v))
   140  		if err == nil {
   141  			t.Fatalf("got deleted value %q", v)
   142  		}
   143  	}
   144  }
   145  
   146  func TestLDB_ParallelPutGet(t *testing.T) {
   147  	db, remove := newTestLDB()
   148  	defer remove()
   149  	testParallelPutGet(db, t)
   150  }
   151  
   152  func TestMemoryDB_ParallelPutGet(t *testing.T) {
   153  	testParallelPutGet(ethdb.NewMemDatabase(), t)
   154  }
   155  
   156  func testParallelPutGet(db ethdb.Database, t *testing.T) {
   157  	const n = 8
   158  	var pending sync.WaitGroup
   159  
   160  	pending.Add(n)
   161  	for i := 0; i < n; i++ {
   162  		go func(key string) {
   163  			defer pending.Done()
   164  			err := db.Put([]byte(key), []byte("v"+key))
   165  			if err != nil {
   166  				panic("put failed: " + err.Error())
   167  			}
   168  		}(strconv.Itoa(i))
   169  	}
   170  	pending.Wait()
   171  
   172  	pending.Add(n)
   173  	for i := 0; i < n; i++ {
   174  		go func(key string) {
   175  			defer pending.Done()
   176  			data, err := db.Get([]byte(key))
   177  			if err != nil {
   178  				panic("get failed: " + err.Error())
   179  			}
   180  			if !bytes.Equal(data, []byte("v"+key)) {
   181  				panic(fmt.Sprintf("get failed, got %q expected %q", []byte(data), []byte("v"+key)))
   182  			}
   183  		}(strconv.Itoa(i))
   184  	}
   185  	pending.Wait()
   186  
   187  	pending.Add(n)
   188  	for i := 0; i < n; i++ {
   189  		go func(key string) {
   190  			defer pending.Done()
   191  			err := db.Delete([]byte(key))
   192  			if err != nil {
   193  				panic("delete failed: " + err.Error())
   194  			}
   195  		}(strconv.Itoa(i))
   196  	}
   197  	pending.Wait()
   198  
   199  	pending.Add(n)
   200  	for i := 0; i < n; i++ {
   201  		go func(key string) {
   202  			defer pending.Done()
   203  			_, err := db.Get([]byte(key))
   204  			if err == nil {
   205  				panic("get succeeded")
   206  			}
   207  		}(strconv.Itoa(i))
   208  	}
   209  	pending.Wait()
   210  }
   211