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