github.com/adnan-c/fabric_e2e_couchdb@v0.6.1-preview.0.20170228180935-21ce6b23cf91/orderer/common/deliver/deliver_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 deliver 18 19 import ( 20 "fmt" 21 "testing" 22 "time" 23 24 "github.com/hyperledger/fabric/common/configtx/tool/provisional" 25 configvaluesapi "github.com/hyperledger/fabric/common/configvalues" 26 mockconfigvaluesorderer "github.com/hyperledger/fabric/common/mocks/configvalues/channel/orderer" 27 mockpolicies "github.com/hyperledger/fabric/common/mocks/policies" 28 "github.com/hyperledger/fabric/common/policies" 29 ordererledger "github.com/hyperledger/fabric/orderer/ledger" 30 ramledger "github.com/hyperledger/fabric/orderer/ledger/ram" 31 cb "github.com/hyperledger/fabric/protos/common" 32 ab "github.com/hyperledger/fabric/protos/orderer" 33 "github.com/hyperledger/fabric/protos/utils" 34 logging "github.com/op/go-logging" 35 "google.golang.org/grpc" 36 ) 37 38 var genesisBlock = cb.NewBlock(0, nil) 39 40 var systemChainID = "systemChain" 41 42 const ledgerSize = 10 43 44 func init() { 45 logging.SetLevel(logging.DEBUG, "") 46 } 47 48 type mockD struct { 49 grpc.ServerStream 50 recvChan chan *cb.Envelope 51 sendChan chan *ab.DeliverResponse 52 } 53 54 func newMockD() *mockD { 55 return &mockD{ 56 recvChan: make(chan *cb.Envelope), 57 sendChan: make(chan *ab.DeliverResponse), 58 } 59 } 60 61 func (m *mockD) Send(br *ab.DeliverResponse) error { 62 m.sendChan <- br 63 return nil 64 } 65 66 func (m *mockD) Recv() (*cb.Envelope, error) { 67 msg, ok := <-m.recvChan 68 if !ok { 69 return msg, fmt.Errorf("Channel closed") 70 } 71 return msg, nil 72 } 73 74 type mockSupportManager struct { 75 chains map[string]*mockSupport 76 } 77 78 func (mm *mockSupportManager) GetChain(chainID string) (Support, bool) { 79 cs, ok := mm.chains[chainID] 80 return cs, ok 81 } 82 83 type mockSupport struct { 84 ledger ordererledger.ReadWriter 85 sharedConfig *mockconfigvaluesorderer.SharedConfig 86 policyManager *mockpolicies.Manager 87 } 88 89 func (mcs *mockSupport) PolicyManager() policies.Manager { 90 return mcs.policyManager 91 } 92 93 func (mcs *mockSupport) Reader() ordererledger.Reader { 94 return mcs.ledger 95 } 96 97 func NewRAMLedger() ordererledger.ReadWriter { 98 rlf := ramledger.New(ledgerSize + 1) 99 rl, _ := rlf.GetOrCreate(provisional.TestChainID) 100 rl.Append(genesisBlock) 101 return rl 102 } 103 104 func (mcs *mockSupport) SharedConfig() configvaluesapi.Orderer { 105 return mcs.sharedConfig 106 } 107 108 func newMockMultichainManager() *mockSupportManager { 109 rl := NewRAMLedger() 110 mm := &mockSupportManager{ 111 chains: make(map[string]*mockSupport), 112 } 113 mm.chains[systemChainID] = &mockSupport{ 114 ledger: rl, 115 sharedConfig: &mockconfigvaluesorderer.SharedConfig{EgressPolicyNamesVal: []string{"somePolicy"}}, 116 policyManager: &mockpolicies.Manager{Policy: &mockpolicies.Policy{}}, 117 } 118 return mm 119 } 120 121 var seekOldest = &ab.SeekPosition{Type: &ab.SeekPosition_Oldest{&ab.SeekOldest{}}} 122 var seekNewest = &ab.SeekPosition{Type: &ab.SeekPosition_Newest{&ab.SeekNewest{}}} 123 124 func seekSpecified(number uint64) *ab.SeekPosition { 125 return &ab.SeekPosition{Type: &ab.SeekPosition_Specified{&ab.SeekSpecified{Number: number}}} 126 } 127 128 func makeSeek(chainID string, seekInfo *ab.SeekInfo) *cb.Envelope { 129 return &cb.Envelope{ 130 Payload: utils.MarshalOrPanic(&cb.Payload{ 131 Header: &cb.Header{ 132 ChannelHeader: utils.MarshalOrPanic(&cb.ChannelHeader{ 133 ChannelId: chainID, 134 }), 135 SignatureHeader: utils.MarshalOrPanic(&cb.SignatureHeader{}), 136 }, 137 Data: utils.MarshalOrPanic(seekInfo), 138 }), 139 } 140 } 141 142 func TestOldestSeek(t *testing.T) { 143 mm := newMockMultichainManager() 144 for i := 1; i < ledgerSize; i++ { 145 ledger := mm.chains[systemChainID].ledger 146 ledger.Append(ordererledger.CreateNextBlock(ledger, []*cb.Envelope{&cb.Envelope{Payload: []byte(fmt.Sprintf("%d", i))}})) 147 } 148 149 m := newMockD() 150 defer close(m.recvChan) 151 ds := NewHandlerImpl(mm) 152 153 go ds.Handle(m) 154 155 m.recvChan <- makeSeek(systemChainID, &ab.SeekInfo{Start: seekOldest, Stop: seekNewest, Behavior: ab.SeekInfo_BLOCK_UNTIL_READY}) 156 157 count := uint64(0) 158 for { 159 select { 160 case deliverReply := <-m.sendChan: 161 if deliverReply.GetBlock() == nil { 162 if deliverReply.GetStatus() != cb.Status_SUCCESS { 163 t.Fatalf("Received an error on the reply channel") 164 } 165 if count != ledgerSize { 166 t.Fatalf("Expected %d blocks but got %d", ledgerSize, count) 167 } 168 return 169 } else { 170 if deliverReply.GetBlock().Header.Number != count { 171 t.Fatalf("Expected block %d but got block %d", count, deliverReply.GetBlock().Header.Number) 172 } 173 } 174 case <-time.After(time.Second): 175 t.Fatalf("Timed out waiting to get all blocks") 176 } 177 count++ 178 } 179 } 180 181 func TestNewestSeek(t *testing.T) { 182 mm := newMockMultichainManager() 183 for i := 1; i < ledgerSize; i++ { 184 ledger := mm.chains[systemChainID].ledger 185 ledger.Append(ordererledger.CreateNextBlock(ledger, []*cb.Envelope{&cb.Envelope{Payload: []byte(fmt.Sprintf("%d", i))}})) 186 } 187 188 m := newMockD() 189 defer close(m.recvChan) 190 ds := NewHandlerImpl(mm) 191 192 go ds.Handle(m) 193 194 m.recvChan <- makeSeek(systemChainID, &ab.SeekInfo{Start: seekNewest, Stop: seekNewest, Behavior: ab.SeekInfo_BLOCK_UNTIL_READY}) 195 196 select { 197 case deliverReply := <-m.sendChan: 198 if deliverReply.GetBlock() == nil { 199 if deliverReply.GetStatus() != cb.Status_SUCCESS { 200 t.Fatalf("Received an error on the reply channel") 201 } 202 return 203 } else { 204 if deliverReply.GetBlock().Header.Number != uint64(ledgerSize-1) { 205 t.Fatalf("Expected only the most recent block") 206 } 207 } 208 case <-time.After(time.Second): 209 t.Fatalf("Timed out waiting to get all blocks") 210 } 211 } 212 213 func TestSpecificSeek(t *testing.T) { 214 mm := newMockMultichainManager() 215 for i := 1; i < ledgerSize; i++ { 216 ledger := mm.chains[systemChainID].ledger 217 ledger.Append(ordererledger.CreateNextBlock(ledger, []*cb.Envelope{&cb.Envelope{Payload: []byte(fmt.Sprintf("%d", i))}})) 218 } 219 220 m := newMockD() 221 defer close(m.recvChan) 222 ds := NewHandlerImpl(mm) 223 specifiedStart := uint64(3) 224 specifiedStop := uint64(7) 225 226 go ds.Handle(m) 227 228 m.recvChan <- makeSeek(systemChainID, &ab.SeekInfo{Start: seekSpecified(specifiedStart), Stop: seekSpecified(specifiedStop), Behavior: ab.SeekInfo_BLOCK_UNTIL_READY}) 229 230 count := uint64(0) 231 for { 232 select { 233 case deliverReply := <-m.sendChan: 234 if deliverReply.GetBlock() == nil { 235 if deliverReply.GetStatus() != cb.Status_SUCCESS { 236 t.Fatalf("Received an error on the reply channel") 237 } 238 return 239 } else { 240 if expected := specifiedStart + count; deliverReply.GetBlock().Header.Number != expected { 241 t.Fatalf("Expected block %d but got block %d", expected, deliverReply.GetBlock().Header.Number) 242 } 243 } 244 case <-time.After(time.Second): 245 t.Fatalf("Timed out waiting to get all blocks") 246 } 247 count++ 248 } 249 } 250 251 func TestUnauthorizedSeek(t *testing.T) { 252 mm := newMockMultichainManager() 253 for i := 1; i < ledgerSize; i++ { 254 ledger := mm.chains[systemChainID].ledger 255 ledger.Append(ordererledger.CreateNextBlock(ledger, []*cb.Envelope{&cb.Envelope{Payload: []byte(fmt.Sprintf("%d", i))}})) 256 } 257 mm.chains[systemChainID].policyManager.Policy.Err = fmt.Errorf("Fail to evaluate policy") 258 259 m := newMockD() 260 defer close(m.recvChan) 261 ds := NewHandlerImpl(mm) 262 263 go ds.Handle(m) 264 265 m.recvChan <- makeSeek(systemChainID, &ab.SeekInfo{Start: seekSpecified(uint64(0)), Stop: seekSpecified(uint64(0)), Behavior: ab.SeekInfo_BLOCK_UNTIL_READY}) 266 267 select { 268 case deliverReply := <-m.sendChan: 269 if deliverReply.GetStatus() != cb.Status_FORBIDDEN { 270 t.Fatalf("Received wrong error on the reply channel") 271 } 272 case <-time.After(time.Second): 273 t.Fatalf("Timed out waiting to get all blocks") 274 } 275 } 276 277 func TestBadSeek(t *testing.T) { 278 mm := newMockMultichainManager() 279 for i := 1; i < ledgerSize; i++ { 280 ledger := mm.chains[systemChainID].ledger 281 ledger.Append(ordererledger.CreateNextBlock(ledger, []*cb.Envelope{&cb.Envelope{Payload: []byte(fmt.Sprintf("%d", i))}})) 282 } 283 284 m := newMockD() 285 defer close(m.recvChan) 286 ds := NewHandlerImpl(mm) 287 288 go ds.Handle(m) 289 290 m.recvChan <- makeSeek(systemChainID, &ab.SeekInfo{Start: seekSpecified(uint64(3 * ledgerSize)), Stop: seekSpecified(uint64(3 * ledgerSize)), Behavior: ab.SeekInfo_BLOCK_UNTIL_READY}) 291 292 select { 293 case deliverReply := <-m.sendChan: 294 if deliverReply.GetStatus() != cb.Status_NOT_FOUND { 295 t.Fatalf("Received wrong error on the reply channel") 296 } 297 case <-time.After(time.Second): 298 t.Fatalf("Timed out waiting to get all blocks") 299 } 300 } 301 302 func TestFailFastSeek(t *testing.T) { 303 mm := newMockMultichainManager() 304 for i := 1; i < ledgerSize; i++ { 305 ledger := mm.chains[systemChainID].ledger 306 ledger.Append(ordererledger.CreateNextBlock(ledger, []*cb.Envelope{&cb.Envelope{Payload: []byte(fmt.Sprintf("%d", i))}})) 307 } 308 309 m := newMockD() 310 defer close(m.recvChan) 311 ds := NewHandlerImpl(mm) 312 313 go ds.Handle(m) 314 315 m.recvChan <- makeSeek(systemChainID, &ab.SeekInfo{Start: seekSpecified(uint64(ledgerSize - 1)), Stop: seekSpecified(ledgerSize), Behavior: ab.SeekInfo_FAIL_IF_NOT_READY}) 316 317 select { 318 case deliverReply := <-m.sendChan: 319 if deliverReply.GetBlock() == nil { 320 t.Fatalf("Expected to receive first block") 321 } 322 case <-time.After(time.Second): 323 t.Fatalf("Timed out waiting to get all blocks") 324 } 325 326 select { 327 case deliverReply := <-m.sendChan: 328 if deliverReply.GetStatus() != cb.Status_NOT_FOUND { 329 t.Fatalf("Expected to receive failure for second block") 330 } 331 case <-time.After(time.Second): 332 t.Fatalf("Timed out waiting to get all blocks") 333 } 334 } 335 336 func TestBlockingSeek(t *testing.T) { 337 mm := newMockMultichainManager() 338 for i := 1; i < ledgerSize; i++ { 339 ledger := mm.chains[systemChainID].ledger 340 ledger.Append(ordererledger.CreateNextBlock(ledger, []*cb.Envelope{&cb.Envelope{Payload: []byte(fmt.Sprintf("%d", i))}})) 341 } 342 343 m := newMockD() 344 defer close(m.recvChan) 345 ds := NewHandlerImpl(mm) 346 347 go ds.Handle(m) 348 349 m.recvChan <- makeSeek(systemChainID, &ab.SeekInfo{Start: seekSpecified(uint64(ledgerSize - 1)), Stop: seekSpecified(ledgerSize), Behavior: ab.SeekInfo_BLOCK_UNTIL_READY}) 350 351 select { 352 case deliverReply := <-m.sendChan: 353 if deliverReply.GetBlock() == nil { 354 t.Fatalf("Expected to receive first block") 355 } 356 case <-time.After(time.Second): 357 t.Fatalf("Timed out waiting to get first block") 358 } 359 360 select { 361 case <-m.sendChan: 362 t.Fatalf("Should not have delivered an error or second block") 363 case <-time.After(50 * time.Millisecond): 364 } 365 366 ledger := mm.chains[systemChainID].ledger 367 ledger.Append(ordererledger.CreateNextBlock(ledger, []*cb.Envelope{&cb.Envelope{Payload: []byte(fmt.Sprintf("%d", ledgerSize+1))}})) 368 369 select { 370 case deliverReply := <-m.sendChan: 371 if deliverReply.GetBlock() == nil { 372 t.Fatalf("Expected to receive new block") 373 } 374 case <-time.After(time.Second): 375 t.Fatalf("Timed out waiting to get new block") 376 } 377 378 select { 379 case deliverReply := <-m.sendChan: 380 if deliverReply.GetStatus() != cb.Status_SUCCESS { 381 t.Fatalf("Expected delivery to complete") 382 } 383 case <-time.After(time.Second): 384 t.Fatalf("Timed out waiting to get all blocks") 385 } 386 }