github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/swarm/storage/memstore_test.go (about)

     1  
     2  //此源码被清华学神尹成大魔王专业翻译分析并修改
     3  //尹成QQ77025077
     4  //尹成微信18510341407
     5  //尹成所在QQ群721929980
     6  //尹成邮箱 yinc13@mails.tsinghua.edu.cn
     7  //尹成毕业于清华大学,微软区块链领域全球最有价值专家
     8  //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620
     9  //
    10  //
    11  //
    12  //
    13  //
    14  //
    15  //
    16  //
    17  //
    18  //
    19  //
    20  //
    21  //
    22  //
    23  //
    24  
    25  package storage
    26  
    27  import (
    28  	"context"
    29  	"crypto/rand"
    30  	"encoding/binary"
    31  	"io/ioutil"
    32  	"os"
    33  	"sync"
    34  	"testing"
    35  
    36  	"github.com/ethereum/go-ethereum/swarm/log"
    37  )
    38  
    39  func newTestMemStore() *MemStore {
    40  	storeparams := NewDefaultStoreParams()
    41  	return NewMemStore(storeparams, nil)
    42  }
    43  
    44  func testMemStoreRandom(n int, processors int, chunksize int64, t *testing.T) {
    45  	m := newTestMemStore()
    46  	defer m.Close()
    47  	testStoreRandom(m, processors, n, chunksize, t)
    48  }
    49  
    50  func testMemStoreCorrect(n int, processors int, chunksize int64, t *testing.T) {
    51  	m := newTestMemStore()
    52  	defer m.Close()
    53  	testStoreCorrect(m, processors, n, chunksize, t)
    54  }
    55  
    56  func TestMemStoreRandom_1(t *testing.T) {
    57  	testMemStoreRandom(1, 1, 0, t)
    58  }
    59  
    60  func TestMemStoreCorrect_1(t *testing.T) {
    61  	testMemStoreCorrect(1, 1, 4104, t)
    62  }
    63  
    64  func TestMemStoreRandom_1_1k(t *testing.T) {
    65  	testMemStoreRandom(1, 1000, 0, t)
    66  }
    67  
    68  func TestMemStoreCorrect_1_1k(t *testing.T) {
    69  	testMemStoreCorrect(1, 100, 4096, t)
    70  }
    71  
    72  func TestMemStoreRandom_8_1k(t *testing.T) {
    73  	testMemStoreRandom(8, 1000, 0, t)
    74  }
    75  
    76  func TestMemStoreCorrect_8_1k(t *testing.T) {
    77  	testMemStoreCorrect(8, 1000, 4096, t)
    78  }
    79  
    80  func TestMemStoreNotFound(t *testing.T) {
    81  	m := newTestMemStore()
    82  	defer m.Close()
    83  
    84  	_, err := m.Get(context.TODO(), ZeroAddr)
    85  	if err != ErrChunkNotFound {
    86  		t.Errorf("Expected ErrChunkNotFound, got %v", err)
    87  	}
    88  }
    89  
    90  func benchmarkMemStorePut(n int, processors int, chunksize int64, b *testing.B) {
    91  	m := newTestMemStore()
    92  	defer m.Close()
    93  	benchmarkStorePut(m, processors, n, chunksize, b)
    94  }
    95  
    96  func benchmarkMemStoreGet(n int, processors int, chunksize int64, b *testing.B) {
    97  	m := newTestMemStore()
    98  	defer m.Close()
    99  	benchmarkStoreGet(m, processors, n, chunksize, b)
   100  }
   101  
   102  func BenchmarkMemStorePut_1_500(b *testing.B) {
   103  	benchmarkMemStorePut(500, 1, 4096, b)
   104  }
   105  
   106  func BenchmarkMemStorePut_8_500(b *testing.B) {
   107  	benchmarkMemStorePut(500, 8, 4096, b)
   108  }
   109  
   110  func BenchmarkMemStoreGet_1_500(b *testing.B) {
   111  	benchmarkMemStoreGet(500, 1, 4096, b)
   112  }
   113  
   114  func BenchmarkMemStoreGet_8_500(b *testing.B) {
   115  	benchmarkMemStoreGet(500, 8, 4096, b)
   116  }
   117  
   118  func newLDBStore(t *testing.T) (*LDBStore, func()) {
   119  	dir, err := ioutil.TempDir("", "bzz-storage-test")
   120  	if err != nil {
   121  		t.Fatal(err)
   122  	}
   123  	log.Trace("memstore.tempdir", "dir", dir)
   124  
   125  	ldbparams := NewLDBStoreParams(NewDefaultStoreParams(), dir)
   126  	db, err := NewLDBStore(ldbparams)
   127  	if err != nil {
   128  		t.Fatal(err)
   129  	}
   130  
   131  	cleanup := func() {
   132  		db.Close()
   133  		err := os.RemoveAll(dir)
   134  		if err != nil {
   135  			t.Fatal(err)
   136  		}
   137  	}
   138  
   139  	return db, cleanup
   140  }
   141  
   142  func TestMemStoreAndLDBStore(t *testing.T) {
   143  	ldb, cleanup := newLDBStore(t)
   144  	ldb.setCapacity(4000)
   145  	defer cleanup()
   146  
   147  	cacheCap := 200
   148  	requestsCap := 200
   149  	memStore := NewMemStore(NewStoreParams(4000, 200, 200, nil, nil), nil)
   150  
   151  	tests := []struct {
   152  n         int    //
   153  chunkSize uint64 //
   154  request   bool   //
   155  	}{
   156  		{
   157  			n:         1,
   158  			chunkSize: 4096,
   159  			request:   false,
   160  		},
   161  		{
   162  			n:         201,
   163  			chunkSize: 4096,
   164  			request:   false,
   165  		},
   166  		{
   167  			n:         501,
   168  			chunkSize: 4096,
   169  			request:   false,
   170  		},
   171  		{
   172  			n:         3100,
   173  			chunkSize: 4096,
   174  			request:   false,
   175  		},
   176  		{
   177  			n:         100,
   178  			chunkSize: 4096,
   179  			request:   true,
   180  		},
   181  	}
   182  
   183  	for i, tt := range tests {
   184  		log.Info("running test", "idx", i, "tt", tt)
   185  		var chunks []*Chunk
   186  
   187  		for i := 0; i < tt.n; i++ {
   188  			var c *Chunk
   189  			if tt.request {
   190  				c = NewRandomRequestChunk(tt.chunkSize)
   191  			} else {
   192  				c = NewRandomChunk(tt.chunkSize)
   193  			}
   194  
   195  			chunks = append(chunks, c)
   196  		}
   197  
   198  		for i := 0; i < tt.n; i++ {
   199  			go ldb.Put(context.TODO(), chunks[i])
   200  			memStore.Put(context.TODO(), chunks[i])
   201  
   202  			if got := memStore.cache.Len(); got > cacheCap {
   203  				t.Fatalf("expected to get cache capacity less than %v, but got %v", cacheCap, got)
   204  			}
   205  
   206  			if got := memStore.requests.Len(); got > requestsCap {
   207  				t.Fatalf("expected to get requests capacity less than %v, but got %v", requestsCap, got)
   208  			}
   209  		}
   210  
   211  		for i := 0; i < tt.n; i++ {
   212  			_, err := memStore.Get(context.TODO(), chunks[i].Addr)
   213  			if err != nil {
   214  				if err == ErrChunkNotFound {
   215  					_, err := ldb.Get(context.TODO(), chunks[i].Addr)
   216  					if err != nil {
   217  						t.Fatalf("couldn't get chunk %v from ldb, got error: %v", i, err)
   218  					}
   219  				} else {
   220  					t.Fatalf("got error from memstore: %v", err)
   221  				}
   222  			}
   223  		}
   224  
   225  //
   226  		for i := 0; i < tt.n; i++ {
   227  			<-chunks[i].dbStoredC
   228  		}
   229  	}
   230  }
   231  
   232  func NewRandomChunk(chunkSize uint64) *Chunk {
   233  	c := &Chunk{
   234  		Addr:       make([]byte, 32),
   235  		ReqC:       nil,
   236  SData:      make([]byte, chunkSize+8), //
   237  		dbStoredC:  make(chan bool),
   238  		dbStoredMu: &sync.Mutex{},
   239  	}
   240  
   241  	rand.Read(c.SData)
   242  
   243  	binary.LittleEndian.PutUint64(c.SData[:8], chunkSize)
   244  
   245  	hasher := MakeHashFunc(SHA3Hash)()
   246  	hasher.Write(c.SData)
   247  	copy(c.Addr, hasher.Sum(nil))
   248  
   249  	return c
   250  }
   251  
   252  func NewRandomRequestChunk(chunkSize uint64) *Chunk {
   253  	c := NewRandomChunk(chunkSize)
   254  	c.ReqC = make(chan bool)
   255  
   256  	return c
   257  }