github.com/kchristidis/fabric@v1.0.4-0.20171028114726-837acd08cde1/orderer/ledger/blackbox_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 ledger_test 18 19 import ( 20 "bytes" 21 "reflect" 22 "testing" 23 24 . "github.com/hyperledger/fabric/orderer/ledger" 25 cb "github.com/hyperledger/fabric/protos/common" 26 ab "github.com/hyperledger/fabric/protos/orderer" 27 ) 28 29 type ledgerTestable interface { 30 Initialize() (ledgerTestFactory, error) 31 Name() string 32 } 33 34 type ledgerTestFactory interface { 35 New() (Factory, ReadWriter) 36 Destroy() error 37 Persistent() bool 38 } 39 40 var testables []ledgerTestable 41 42 func allTest(t *testing.T, test func(ledgerTestFactory, *testing.T)) { 43 for _, lt := range testables { 44 45 t.Log("Running test for", lt.Name()) 46 47 func() { 48 lf, err := lt.Initialize() 49 if err != nil { 50 t.Fatalf("Error initializing %s: %s", lt.Name(), err) 51 } 52 test(lf, t) 53 err = lf.Destroy() 54 if err != nil { 55 t.Fatalf("Error destroying %s: %s", lt.Name(), err) 56 } 57 }() 58 59 t.Log("Completed test successfully for", lt.Name()) 60 } 61 } 62 63 func TestInitialization(t *testing.T) { 64 allTest(t, testInitialization) 65 } 66 67 func testInitialization(lf ledgerTestFactory, t *testing.T) { 68 _, li := lf.New() 69 if li.Height() != 1 { 70 t.Fatalf("Block height should be 1") 71 } 72 block := GetBlock(li, 0) 73 if block == nil { 74 t.Fatalf("Error retrieving genesis block") 75 } 76 77 } 78 79 func TestReinitialization(t *testing.T) { 80 allTest(t, testReinitialization) 81 } 82 83 func testReinitialization(lf ledgerTestFactory, t *testing.T) { 84 if !lf.Persistent() { 85 t.Log("Skipping test as persistence is not available for this ledger type") 86 return 87 } 88 olf, oli := lf.New() 89 aBlock := CreateNextBlock(oli, []*cb.Envelope{&cb.Envelope{Payload: []byte("My Data")}}) 90 err := oli.Append(aBlock) 91 if err != nil { 92 t.Fatalf("Error appending block: %s", err) 93 } 94 olf.Close() 95 96 _, li := lf.New() 97 if li.Height() != 2 { 98 t.Fatalf("Block height should be 2") 99 } 100 block := GetBlock(li, 1) 101 if block == nil { 102 t.Fatalf("Error retrieving block 1") 103 } 104 if !bytes.Equal(block.Header.Hash(), aBlock.Header.Hash()) { 105 t.Fatalf("Block hashes did no match") 106 } 107 } 108 109 func TestAddition(t *testing.T) { 110 allTest(t, testAddition) 111 } 112 113 func testAddition(lf ledgerTestFactory, t *testing.T) { 114 _, li := lf.New() 115 genesis := GetBlock(li, 0) 116 if genesis == nil { 117 t.Fatalf("Could not retrieve genesis block") 118 } 119 prevHash := genesis.Header.Hash() 120 121 li.Append(CreateNextBlock(li, []*cb.Envelope{&cb.Envelope{Payload: []byte("My Data")}})) 122 if li.Height() != 2 { 123 t.Fatalf("Block height should be 2") 124 } 125 block := GetBlock(li, 1) 126 if block == nil { 127 t.Fatalf("Error retrieving genesis block") 128 } 129 if !bytes.Equal(block.Header.PreviousHash, prevHash) { 130 t.Fatalf("Block hashes did no match") 131 } 132 } 133 134 func TestRetrieval(t *testing.T) { 135 allTest(t, testRetrieval) 136 } 137 138 func testRetrieval(lf ledgerTestFactory, t *testing.T) { 139 _, li := lf.New() 140 li.Append(CreateNextBlock(li, []*cb.Envelope{&cb.Envelope{Payload: []byte("My Data")}})) 141 it, num := li.Iterator(&ab.SeekPosition{Type: &ab.SeekPosition_Oldest{}}) 142 if num != 0 { 143 t.Fatalf("Expected genesis block iterator, but got %d", num) 144 } 145 signal := it.ReadyChan() 146 select { 147 case <-signal: 148 default: 149 t.Fatalf("Should be ready for block read") 150 } 151 block, status := it.Next() 152 if status != cb.Status_SUCCESS { 153 t.Fatalf("Expected to successfully read the genesis block") 154 } 155 if block.Header.Number != 0 { 156 t.Fatalf("Expected to successfully retrieve the genesis block") 157 } 158 signal = it.ReadyChan() 159 select { 160 case <-signal: 161 default: 162 t.Fatalf("Should still be ready for block read") 163 } 164 block, status = it.Next() 165 if status != cb.Status_SUCCESS { 166 t.Fatalf("Expected to successfully read the second block") 167 } 168 if block.Header.Number != 1 { 169 t.Fatalf("Expected to successfully retrieve the second block but got block number %d", block.Header.Number) 170 } 171 } 172 173 func TestBlockedRetrieval(t *testing.T) { 174 allTest(t, testBlockedRetrieval) 175 } 176 177 func testBlockedRetrieval(lf ledgerTestFactory, t *testing.T) { 178 _, li := lf.New() 179 it, num := li.Iterator(&ab.SeekPosition{Type: &ab.SeekPosition_Specified{Specified: &ab.SeekSpecified{Number: 1}}}) 180 if num != 1 { 181 t.Fatalf("Expected block iterator at 1, but got %d", num) 182 } 183 signal := it.ReadyChan() 184 select { 185 case <-signal: 186 t.Fatalf("Should not be ready for block read") 187 default: 188 } 189 li.Append(CreateNextBlock(li, []*cb.Envelope{&cb.Envelope{Payload: []byte("My Data")}})) 190 select { 191 case <-signal: 192 default: 193 t.Fatalf("Should now be ready for block read") 194 } 195 block, status := it.Next() 196 if status != cb.Status_SUCCESS { 197 t.Fatalf("Expected to successfully read the second block") 198 } 199 if block.Header.Number != 1 { 200 t.Fatalf("Expected to successfully retrieve the second block") 201 } 202 } 203 204 func TestMultichain(t *testing.T) { 205 allTest(t, testMultichain) 206 } 207 208 func testMultichain(lf ledgerTestFactory, t *testing.T) { 209 f, _ := lf.New() 210 chain1 := "chain1" 211 chain2 := "chain2" 212 213 c1p1 := []byte("c1 payload1") 214 c1p2 := []byte("c1 payload2") 215 216 c2p1 := []byte("c2 payload1") 217 218 c1, err := f.GetOrCreate(chain1) 219 if err != nil { 220 t.Fatalf("Error creating chain1: %s", err) 221 } 222 223 c1.Append(CreateNextBlock(c1, []*cb.Envelope{&cb.Envelope{Payload: c1p1}})) 224 c1b1 := CreateNextBlock(c1, []*cb.Envelope{&cb.Envelope{Payload: c1p2}}) 225 c1.Append(c1b1) 226 227 if c1.Height() != 2 { 228 t.Fatalf("Block height for c1 should be 2") 229 } 230 231 c2, err := f.GetOrCreate(chain2) 232 if err != nil { 233 t.Fatalf("Error creating chain2: %s", err) 234 } 235 c2b0 := c2.Append(CreateNextBlock(c2, []*cb.Envelope{&cb.Envelope{Payload: c2p1}})) 236 237 if c2.Height() != 1 { 238 t.Fatalf("Block height for c2 should be 1") 239 } 240 241 c1, err = f.GetOrCreate(chain1) 242 if err != nil { 243 t.Fatalf("Error retrieving chain1: %s", err) 244 } 245 246 if b := GetBlock(c1, 1); !reflect.DeepEqual(c1b1, b) { 247 t.Fatalf("Did not properly store block 1 on chain 1:") 248 } 249 250 c2, err = f.GetOrCreate(chain1) 251 if err != nil { 252 t.Fatalf("Error retrieving chain2: %s", err) 253 } 254 255 if b := GetBlock(c2, 0); reflect.DeepEqual(c2b0, b) { 256 t.Fatalf("Did not properly store block 1 on chain 1") 257 } 258 }