diff --git a/orderer/ledger/ram/factory_test.go b/orderer/ledger/ram/factory_test.go new file mode 100644 index 00000000000..d1e84c0c0eb --- /dev/null +++ b/orderer/ledger/ram/factory_test.go @@ -0,0 +1,55 @@ +/* +Copyright IBM Corp. 2016 All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package ramledger + +import ( + "testing" + + "github.com/hyperledger/fabric/common/configtx/tool/provisional" + + logging "github.com/op/go-logging" +) + +func init() { + logging.SetLevel(logging.DEBUG, "") +} + +func TestGetOrCreate(t *testing.T) { + rlf := New(3) + channel, err := rlf.GetOrCreate(provisional.TestChainID) + if err != nil { + panic(err) + } + channel2, err := rlf.GetOrCreate(provisional.TestChainID) + if err != nil { + panic(err) + } + if channel != channel2 { + t.Fatalf("Expecting already created channel.") + } +} + +func TestChainIDs(t *testing.T) { + rlf := New(3) + rlf.GetOrCreate("channel1") + rlf.GetOrCreate("channel2") + rlf.GetOrCreate("channel3") + if len(rlf.ChainIDs()) != 3 { + t.Fatalf("Expecting three channels,") + } + rlf.Close() +} diff --git a/orderer/ledger/ram/impl_test.go b/orderer/ledger/ram/impl_test.go index 8a8a5d5186f..9261e0c2b1b 100644 --- a/orderer/ledger/ram/impl_test.go +++ b/orderer/ledger/ram/impl_test.go @@ -20,7 +20,9 @@ import ( "testing" "github.com/hyperledger/fabric/common/configtx/tool/provisional" + "github.com/hyperledger/fabric/orderer/ledger" cb "github.com/hyperledger/fabric/protos/common" + ab "github.com/hyperledger/fabric/protos/orderer" logging "github.com/op/go-logging" ) @@ -106,3 +108,103 @@ func TestTruncationSafety(t *testing.T) { t.Fatalf("The iterator should have found %d new blocks but found %d", newBlocks, count) } } + +func TestRetrieval(t *testing.T) { + rl := newTestChain(3) + rl.Append(ledger.CreateNextBlock(rl, []*cb.Envelope{&cb.Envelope{Payload: []byte("My Data")}})) + it, num := rl.Iterator(&ab.SeekPosition{Type: &ab.SeekPosition_Oldest{}}) + if num != 0 { + t.Fatalf("Expected genesis block iterator, but got %d", num) + } + signal := it.ReadyChan() + select { + case <-signal: + default: + t.Fatalf("Should be ready for block read") + } + block, status := it.Next() + if status != cb.Status_SUCCESS { + t.Fatalf("Expected to successfully read the genesis block") + } + if block.Header.Number != 0 { + t.Fatalf("Expected to successfully retrieve the genesis block") + } + signal = it.ReadyChan() + select { + case <-signal: + default: + t.Fatalf("Should still be ready for block read") + } + block, status = it.Next() + if status != cb.Status_SUCCESS { + t.Fatalf("Expected to successfully read the second block") + } + if block.Header.Number != 1 { + t.Fatalf("Expected to successfully retrieve the second block but got block number %d", block.Header.Number) + } +} + +func TestBlockedRetrieval(t *testing.T) { + rl := newTestChain(3) + it, num := rl.Iterator(&ab.SeekPosition{Type: &ab.SeekPosition_Specified{Specified: &ab.SeekSpecified{Number: 1}}}) + if num != 1 { + t.Fatalf("Expected block iterator at 1, but got %d", num) + } + signal := it.ReadyChan() + select { + case <-signal: + t.Fatalf("Should not be ready for block read") + default: + } + rl.Append(ledger.CreateNextBlock(rl, []*cb.Envelope{&cb.Envelope{Payload: []byte("My Data")}})) + select { + case <-signal: + default: + t.Fatalf("Should now be ready for block read") + } + block, status := it.Next() + if status != cb.Status_SUCCESS { + t.Fatalf("Expected to successfully read the second block") + } + if block.Header.Number != 1 { + t.Fatalf("Expected to successfully retrieve the second block") + } +} + +func TestIteratorPastEnd(t *testing.T) { + rl := newTestChain(3) + it, _ := rl.Iterator(&ab.SeekPosition{Type: &ab.SeekPosition_Specified{Specified: &ab.SeekSpecified{Number: 2}}}) + if _, status := it.Next(); status != cb.Status_NOT_FOUND { + t.Fatalf("Expected block with status NOT_FOUND, but got %d", status) + } +} + +func TestIteratorOldest(t *testing.T) { + rl := newTestChain(3) + // add enough block to roll off the genesis block + rl.Append(ledger.CreateNextBlock(rl, []*cb.Envelope{&cb.Envelope{Payload: []byte("My Data")}})) + rl.Append(ledger.CreateNextBlock(rl, []*cb.Envelope{&cb.Envelope{Payload: []byte("My Data")}})) + rl.Append(ledger.CreateNextBlock(rl, []*cb.Envelope{&cb.Envelope{Payload: []byte("My Data")}})) + _, num := rl.Iterator(&ab.SeekPosition{Type: &ab.SeekPosition_Specified{Specified: &ab.SeekSpecified{Number: 1}}}) + if num != 1 { + t.Fatalf("Expected block iterator at 1, but got %d", num) + } +} + +func TestAppendBadBLock(t *testing.T) { + rl := newTestChain(3) + t.Run("BadBlockNumber", func(t *testing.T) { + nextBlock := ledger.CreateNextBlock(rl, []*cb.Envelope{&cb.Envelope{Payload: []byte("My Data")}}) + nextBlock.Header.Number = nextBlock.Header.Number + 1 + if err := rl.Append(nextBlock); err == nil { + t.Fatalf("Expected Append to fail.") + } + }) + t.Run("BadPreviousHash", func(t *testing.T) { + nextBlock := ledger.CreateNextBlock(rl, []*cb.Envelope{&cb.Envelope{Payload: []byte("My Data")}}) + nextBlock.Header.PreviousHash = []byte("bad hash") + if err := rl.Append(nextBlock); err == nil { + t.Fatalf("Expected Append to fail.") + } + }) +}