github.com/tenywen/fabric@v1.0.0-beta.0.20170620030522-a5b1ed380643/orderer/ledger/file/impl_test.go (about)

     1  /*
     2  Copyright IBM Corp. 2016 All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8                   http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package fileledger
    18  
    19  import (
    20  	"bytes"
    21  	"io/ioutil"
    22  	"os"
    23  	"testing"
    24  
    25  	"github.com/hyperledger/fabric/common/configtx/tool/provisional"
    26  	"github.com/hyperledger/fabric/orderer/ledger"
    27  	cb "github.com/hyperledger/fabric/protos/common"
    28  	ab "github.com/hyperledger/fabric/protos/orderer"
    29  
    30  	logging "github.com/op/go-logging"
    31  )
    32  
    33  var genesisBlock = cb.NewBlock(0, nil)
    34  
    35  func init() {
    36  	logging.SetLevel(logging.DEBUG, "")
    37  }
    38  
    39  type testEnv struct {
    40  	t        *testing.T
    41  	location string
    42  	flf      ledger.Factory
    43  }
    44  
    45  func initialize(t *testing.T) (*testEnv, *fileLedger) {
    46  	name, err := ioutil.TempDir("", "hyperledger_fabric")
    47  	if err != nil {
    48  		t.Fatalf("Error creating temp dir: %s", err)
    49  	}
    50  	flf := New(name).(*fileLedgerFactory)
    51  	fl, err := flf.GetOrCreate(provisional.TestChainID)
    52  	if err != nil {
    53  		panic(err)
    54  	}
    55  	fl.Append(genesisBlock)
    56  	return &testEnv{location: name, t: t, flf: flf}, fl.(*fileLedger)
    57  }
    58  
    59  func (tev *testEnv) tearDown() {
    60  	tev.shutDown()
    61  	err := os.RemoveAll(tev.location)
    62  	if err != nil {
    63  		tev.t.Fatalf("Error tearing down env: %s", err)
    64  	}
    65  }
    66  
    67  func (tev *testEnv) shutDown() {
    68  	tev.flf.Close()
    69  }
    70  
    71  func TestInitialization(t *testing.T) {
    72  	tev, fl := initialize(t)
    73  	defer tev.tearDown()
    74  
    75  	if fl.Height() != 1 {
    76  		t.Fatalf("Block height should be 1")
    77  	}
    78  	block := ledger.GetBlock(fl, 0)
    79  	if block == nil {
    80  		t.Fatalf("Error retrieving genesis block")
    81  	}
    82  	if !bytes.Equal(block.Header.Hash(), genesisBlock.Header.Hash()) {
    83  		t.Fatalf("Block hashes did no match")
    84  	}
    85  }
    86  
    87  func TestReinitialization(t *testing.T) {
    88  	// initialize ledger provider and a ledger for the test chain
    89  	tev, leger1 := initialize(t)
    90  
    91  	// make sure we cleanup at the end (delete all traces of ledgers)
    92  	defer tev.tearDown()
    93  
    94  	// create a block to add to the ledger
    95  	b1 := ledger.CreateNextBlock(leger1, []*cb.Envelope{&cb.Envelope{Payload: []byte("My Data")}})
    96  
    97  	// add the block to the ledger
    98  	leger1.Append(b1)
    99  
   100  	// shutdown the ledger
   101  	leger1.blockStore.Shutdown()
   102  
   103  	// shut down the ledger provider
   104  	tev.shutDown()
   105  
   106  	// re-initialize the ledger provider (not the test ledger itself!)
   107  	provider2 := New(tev.location)
   108  
   109  	// assert expected ledgers exist
   110  	chains := provider2.ChainIDs()
   111  	if len(chains) != 1 {
   112  		t.Fatalf("Should have recovered the chain")
   113  	}
   114  
   115  	// get the existing test chain ledger
   116  	ledger2, err := provider2.GetOrCreate(chains[0])
   117  	if err != nil {
   118  		t.Fatalf("Unexpected error: %s", err)
   119  	}
   120  
   121  	fl := ledger2.(*fileLedger)
   122  	if fl.Height() != 2 {
   123  		t.Fatalf("Block height should be 2. Got %v", fl.Height())
   124  	}
   125  	block := ledger.GetBlock(fl, 1)
   126  	if block == nil {
   127  		t.Fatalf("Error retrieving block 1")
   128  	}
   129  	if !bytes.Equal(block.Header.Hash(), b1.Header.Hash()) {
   130  		t.Fatalf("Block hashes did no match")
   131  	}
   132  }
   133  
   134  func TestMultiReinitialization(t *testing.T) {
   135  	tev, _ := initialize(t)
   136  	defer tev.tearDown()
   137  	tev.shutDown()
   138  	flf := New(tev.location)
   139  
   140  	_, err := flf.GetOrCreate("foo")
   141  	if err != nil {
   142  		t.Fatalf("Error creating chain")
   143  	}
   144  
   145  	_, err = flf.GetOrCreate("bar")
   146  	if err != nil {
   147  		t.Fatalf("Error creating chain")
   148  	}
   149  	flf.Close()
   150  	flf = New(tev.location)
   151  	chains := flf.ChainIDs()
   152  	if len(chains) != 3 {
   153  		t.Fatalf("Should have recovered the chains")
   154  	}
   155  }
   156  
   157  func TestAddition(t *testing.T) {
   158  	tev, fl := initialize(t)
   159  	defer tev.tearDown()
   160  	info, _ := fl.blockStore.GetBlockchainInfo()
   161  	prevHash := info.CurrentBlockHash
   162  	fl.Append(ledger.CreateNextBlock(fl, []*cb.Envelope{&cb.Envelope{Payload: []byte("My Data")}}))
   163  	if fl.Height() != 2 {
   164  		t.Fatalf("Block height should be 2")
   165  	}
   166  	block := ledger.GetBlock(fl, 1)
   167  	if block == nil {
   168  		t.Fatalf("Error retrieving genesis block")
   169  	}
   170  	if !bytes.Equal(block.Header.PreviousHash, prevHash) {
   171  		t.Fatalf("Block hashes did no match")
   172  	}
   173  }
   174  
   175  func TestRetrieval(t *testing.T) {
   176  	tev, fl := initialize(t)
   177  	defer tev.tearDown()
   178  	fl.Append(ledger.CreateNextBlock(fl, []*cb.Envelope{&cb.Envelope{Payload: []byte("My Data")}}))
   179  	it, num := fl.Iterator(&ab.SeekPosition{Type: &ab.SeekPosition_Oldest{}})
   180  	if num != 0 {
   181  		t.Fatalf("Expected genesis block iterator, but got %d", num)
   182  	}
   183  	signal := it.ReadyChan()
   184  	select {
   185  	case <-signal:
   186  	default:
   187  		t.Fatalf("Should be ready for block read")
   188  	}
   189  	block, status := it.Next()
   190  	if status != cb.Status_SUCCESS {
   191  		t.Fatalf("Expected to successfully read the genesis block")
   192  	}
   193  	if block.Header.Number != 0 {
   194  		t.Fatalf("Expected to successfully retrieve the genesis block")
   195  	}
   196  	signal = it.ReadyChan()
   197  	select {
   198  	case <-signal:
   199  	default:
   200  		t.Fatalf("Should still be ready for block read")
   201  	}
   202  	block, status = it.Next()
   203  	if status != cb.Status_SUCCESS {
   204  		t.Fatalf("Expected to successfully read the second block")
   205  	}
   206  	if block.Header.Number != 1 {
   207  		t.Fatalf("Expected to successfully retrieve the second block but got block number %d", block.Header.Number)
   208  	}
   209  }
   210  
   211  func TestBlockedRetrieval(t *testing.T) {
   212  	tev, fl := initialize(t)
   213  	defer tev.tearDown()
   214  	it, num := fl.Iterator(&ab.SeekPosition{Type: &ab.SeekPosition_Specified{Specified: &ab.SeekSpecified{Number: 1}}})
   215  	if num != 1 {
   216  		t.Fatalf("Expected block iterator at 1, but got %d", num)
   217  	}
   218  	signal := it.ReadyChan()
   219  	select {
   220  	case <-signal:
   221  		t.Fatalf("Should not be ready for block read")
   222  	default:
   223  	}
   224  	fl.Append(ledger.CreateNextBlock(fl, []*cb.Envelope{&cb.Envelope{Payload: []byte("My Data")}}))
   225  	select {
   226  	case <-signal:
   227  	default:
   228  		t.Fatalf("Should now be ready for block read")
   229  	}
   230  	block, status := it.Next()
   231  	if status != cb.Status_SUCCESS {
   232  		t.Fatalf("Expected to successfully read the second block")
   233  	}
   234  	if block.Header.Number != 1 {
   235  		t.Fatalf("Expected to successfully retrieve the second block")
   236  	}
   237  }