github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/swarm/storage/localstore_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:45</date>
    10  //</624450120234045440>
    11  
    12  
    13  package storage
    14  
    15  import (
    16  	"context"
    17  	"io/ioutil"
    18  	"os"
    19  	"testing"
    20  	"time"
    21  
    22  	ch "github.com/ethereum/go-ethereum/swarm/chunk"
    23  )
    24  
    25  var (
    26  	hashfunc = MakeHashFunc(DefaultHash)
    27  )
    28  
    29  //测试内容地址验证器是否正确检查数据
    30  //通过内容地址验证器传递源更新块的测试
    31  //检查资源更新验证器内部正确性的测试在storage/feeds/handler_test.go中找到。
    32  func TestValidator(t *testing.T) {
    33  //设置本地存储
    34  	datadir, err := ioutil.TempDir("", "storage-testvalidator")
    35  	if err != nil {
    36  		t.Fatal(err)
    37  	}
    38  	defer os.RemoveAll(datadir)
    39  
    40  	params := NewDefaultLocalStoreParams()
    41  	params.Init(datadir)
    42  	store, err := NewLocalStore(params, nil)
    43  	if err != nil {
    44  		t.Fatal(err)
    45  	}
    46  
    47  //不带验证器的检验结果,均成功
    48  	chunks := GenerateRandomChunks(259, 2)
    49  	goodChunk := chunks[0]
    50  	badChunk := chunks[1]
    51  	copy(badChunk.Data(), goodChunk.Data())
    52  
    53  	errs := putChunks(store, goodChunk, badChunk)
    54  	if errs[0] != nil {
    55  		t.Fatalf("expected no error on good content address chunk in spite of no validation, but got: %s", err)
    56  	}
    57  	if errs[1] != nil {
    58  		t.Fatalf("expected no error on bad content address chunk in spite of no validation, but got: %s", err)
    59  	}
    60  
    61  //添加内容地址验证程序并检查Puts
    62  //坏的应该失败,好的应该通过。
    63  	store.Validators = append(store.Validators, NewContentAddressValidator(hashfunc))
    64  	chunks = GenerateRandomChunks(ch.DefaultSize, 2)
    65  	goodChunk = chunks[0]
    66  	badChunk = chunks[1]
    67  	copy(badChunk.Data(), goodChunk.Data())
    68  
    69  	errs = putChunks(store, goodChunk, badChunk)
    70  	if errs[0] != nil {
    71  		t.Fatalf("expected no error on good content address chunk with content address validator only, but got: %s", err)
    72  	}
    73  	if errs[1] == nil {
    74  		t.Fatal("expected error on bad content address chunk with content address validator only, but got nil")
    75  	}
    76  
    77  //附加一个始终拒绝的验证器
    78  //坏的应该失败,好的应该通过,
    79  	var negV boolTestValidator
    80  	store.Validators = append(store.Validators, negV)
    81  
    82  	chunks = GenerateRandomChunks(ch.DefaultSize, 2)
    83  	goodChunk = chunks[0]
    84  	badChunk = chunks[1]
    85  	copy(badChunk.Data(), goodChunk.Data())
    86  
    87  	errs = putChunks(store, goodChunk, badChunk)
    88  	if errs[0] != nil {
    89  		t.Fatalf("expected no error on good content address chunk with content address validator only, but got: %s", err)
    90  	}
    91  	if errs[1] == nil {
    92  		t.Fatal("expected error on bad content address chunk with content address validator only, but got nil")
    93  	}
    94  
    95  //附加一个始终批准的验证器
    96  //一切都将通过
    97  	var posV boolTestValidator = true
    98  	store.Validators = append(store.Validators, posV)
    99  
   100  	chunks = GenerateRandomChunks(ch.DefaultSize, 2)
   101  	goodChunk = chunks[0]
   102  	badChunk = chunks[1]
   103  	copy(badChunk.Data(), goodChunk.Data())
   104  
   105  	errs = putChunks(store, goodChunk, badChunk)
   106  	if errs[0] != nil {
   107  		t.Fatalf("expected no error on good content address chunk with content address validator only, but got: %s", err)
   108  	}
   109  	if errs[1] != nil {
   110  		t.Fatalf("expected no error on bad content address chunk in spite of no validation, but got: %s", err)
   111  	}
   112  
   113  }
   114  
   115  type boolTestValidator bool
   116  
   117  func (self boolTestValidator) Validate(chunk Chunk) bool {
   118  	return bool(self)
   119  }
   120  
   121  //PutChunks将块添加到LocalStore
   122  //它等待存储通道上的接收
   123  //它记录但在传递错误时不会失败
   124  func putChunks(store *LocalStore, chunks ...Chunk) []error {
   125  	i := 0
   126  	f := func(n int64) Chunk {
   127  		chunk := chunks[i]
   128  		i++
   129  		return chunk
   130  	}
   131  	_, errs := put(store, len(chunks), f)
   132  	return errs
   133  }
   134  
   135  func put(store *LocalStore, n int, f func(i int64) Chunk) (hs []Address, errs []error) {
   136  	for i := int64(0); i < int64(n); i++ {
   137  		chunk := f(ch.DefaultSize)
   138  		err := store.Put(context.TODO(), chunk)
   139  		errs = append(errs, err)
   140  		hs = append(hs, chunk.Address())
   141  	}
   142  	return hs, errs
   143  }
   144  
   145  //testgetfrequentlyaccessedchunkwontgetgarbag收集的测试
   146  //频繁访问的块不是从ldbstore收集的垃圾,即,
   147  //当我们达到容量并且垃圾收集器运行时,从磁盘开始。为此
   148  //我们开始将随机块放入数据库,同时不断地访问
   149  //我们关心的块,然后检查我们是否仍然可以从磁盘中检索到它。
   150  func TestGetFrequentlyAccessedChunkWontGetGarbageCollected(t *testing.T) {
   151  	ldbCap := defaultGCRatio
   152  	store, cleanup := setupLocalStore(t, ldbCap)
   153  	defer cleanup()
   154  
   155  	var chunks []Chunk
   156  	for i := 0; i < ldbCap; i++ {
   157  		chunks = append(chunks, GenerateRandomChunk(ch.DefaultSize))
   158  	}
   159  
   160  	mostAccessed := chunks[0].Address()
   161  	for _, chunk := range chunks {
   162  		if err := store.Put(context.Background(), chunk); err != nil {
   163  			t.Fatal(err)
   164  		}
   165  
   166  		if _, err := store.Get(context.Background(), mostAccessed); err != nil {
   167  			t.Fatal(err)
   168  		}
   169  //添加markaccessed()在单独的goroutine中完成的时间
   170  		time.Sleep(1 * time.Millisecond)
   171  	}
   172  
   173  	store.DbStore.collectGarbage()
   174  	if _, err := store.DbStore.Get(context.Background(), mostAccessed); err != nil {
   175  		t.Logf("most frequntly accessed chunk not found on disk (key: %v)", mostAccessed)
   176  		t.Fatal(err)
   177  	}
   178  
   179  }
   180  
   181  func setupLocalStore(t *testing.T, ldbCap int) (ls *LocalStore, cleanup func()) {
   182  	t.Helper()
   183  
   184  	var err error
   185  	datadir, err := ioutil.TempDir("", "storage")
   186  	if err != nil {
   187  		t.Fatal(err)
   188  	}
   189  
   190  	params := &LocalStoreParams{
   191  		StoreParams: NewStoreParams(uint64(ldbCap), uint(ldbCap), nil, nil),
   192  	}
   193  	params.Init(datadir)
   194  
   195  	store, err := NewLocalStore(params, nil)
   196  	if err != nil {
   197  		_ = os.RemoveAll(datadir)
   198  		t.Fatal(err)
   199  	}
   200  
   201  	cleanup = func() {
   202  		store.Close()
   203  		_ = os.RemoveAll(datadir)
   204  	}
   205  
   206  	return store, cleanup
   207  }
   208