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 }